云图片手机网站展示广告网站开发背景

张小明 2025/12/22 23:55:33
云图片手机网站展示,广告网站开发背景,wordpress 外部调用,陕西网络推广公司#x1f3af; AOP连接点#xff08;JoinPoint#xff09;详解 连接点是AOP中程序执行过程中的一个特定点#xff0c;它是切面可以插入增强逻辑的位置。#x1f4cd; 连接点是什么#xff1f; 生动的比喻 程序执行就像一部电影 #x1f3ac; 连接点 → 电影的关键帧…AOP连接点JoinPoint详解连接点是AOP中程序执行过程中的一个特定点它是切面可以插入增强逻辑的位置。连接点是什么生动的比喻程序执行就像一部电影 连接点 → 电影的关键帧可以插入特效的地方 切面 → 特效团队 增强 → 实际添加的特效慢动作、滤镜等更技术化的理解连接点是程序运行中可以被拦截的点例如方法调用方法执行异常抛出字段访问对象初始化在Spring AOP中连接点特指方法的执行。连接点的具体形式1. 方法执行Method Execution✅Spring AOP唯一支持的publicclassUserService{publicvoidsaveUser(Useruser){// ← 这是一个连接点// 方法体}}2. 方法调用Method Call❌Spring AOP不支持publicclassController{publicvoidprocess(){userService.saveUser(user);// ← 这是一个调用连接点}}3. 其他连接点AspectJ支持但Spring AOP不支持// 构造器执行newUserService();// ← 连接点// 字段访问user.name;// ← 连接点// 异常处理thrownewException();// ← 连接点JoinPoint对象详解在通知方法中可以通过JoinPoint参数获取连接点信息JoinPoint核心方法publicinterfaceJoinPoint{// 获取方法签名SignaturegetSignature();// 获取目标对象ObjectgetTarget();// 获取代理对象ObjectgetThis();// 获取方法参数Object[]getArgs();// 获取连接点类型Spring AOP中总是method-executionStringgetKind();// 获取静态部分信息JoinPoint.StaticPartgetStaticPart();// 获取源位置信息文件名、行号等SourceLocationgetSourceLocation();}Signature对象publicinterfaceSignature{StringgetName();// 方法名saveUserintgetModifiers();// 修饰符publicClassgetDeclaringType();// 声明类UserServiceStringgetDeclaringTypeName();// 类名com.example.UserService// 更多信息StringtoShortString();// 简短字符串StringtoLongString();// 完整字符串}实际使用示例示例1获取方法信息Before(execution(* com.example.service.*.*(..)))publicvoidbeforeAdvice(JoinPointjoinPoint){// 1. 获取方法签名MethodSignaturesignature(MethodSignature)joinPoint.getSignature();System.out.println( 连接点信息 );System.out.println(方法名: signature.getName());// saveUserSystem.out.println(方法全名: signature.toLongString());// public void com.example.UserService.saveUser(User)System.out.println(声明类: signature.getDeclaringTypeName());// com.example.UserServiceSystem.out.println(返回类型: signature.getReturnType());// void// 2. 获取参数Object[]argsjoinPoint.getArgs();for(inti0;iargs.length;i){System.out.println(参数i: args[i] (类型: signature.getParameterTypes()[i]));}// 3. 目标对象和代理对象System.out.println(目标对象: joinPoint.getTarget().getClass());// UserService$$EnhancerBySpringCGLIBSystem.out.println(代理对象: joinPoint.getThis().getClass());// UserService$$EnhancerBySpringCGLIB}示例2环绕通知中使用ProceedingJoinPointAround(execution(* com.example.service.*.*(..)))publicObjectaroundAdvice(ProceedingJoinPointjoinPoint)throwsThrowable{// ProceedingJoinPoint是JoinPoint的子接口多了proceed()方法System.out.println(【环绕通知开始】方法: joinPoint.getSignature().getName());// 1. 可以修改参数Object[]argsjoinPoint.getArgs();if(args.length0args[0]instanceofString){args[0]((String)args[0]).toUpperCase();// 修改参数}// 2. 执行目标方法longstartSystem.currentTimeMillis();ObjectresultjoinPoint.proceed(args);// 可以传入修改后的参数longendSystem.currentTimeMillis();System.out.println(【环绕通知结束】耗时: (end-start)ms);// 3. 可以修改返回值if(resultinstanceofString){result处理后的结果: result;}returnresult;}连接点 vs 切入点 vs 通知概念定义比喻连接点程序执行中的具体点如方法执行电影中的具体帧切入点匹配连接点的表达式筛选哪些连接点选中的帧的范围如所有打斗场景通知在连接点执行的增强逻辑在选中的帧上添加的特效三者关系AspectComponentpublicclassLogAspect{// 切入点匹配哪些连接点Pointcut(execution(* com.example.service.*.*(..)))publicvoidserviceMethods(){}// ← 切入点表达式// 通知在连接点上执行的逻辑Before(serviceMethods())// ← 应用到切入点匹配的连接点publicvoidlogBefore(JoinPointjoinPoint){// ← JoinPoint代表具体的连接点// 这里是通知逻辑System.out.println(执行方法: joinPoint.getSignature().getName());}}获取连接点信息的实用工具类ComponentpublicclassJoinPointUtils{/** * 获取方法参数Map */publicstaticMapString,ObjectgetArgsMap(JoinPointjoinPoint){MapString,ObjectargsMapnewHashMap();if(joinPoint.getSignature()instanceofMethodSignature){MethodSignaturesignature(MethodSignature)joinPoint.getSignature();String[]parameterNamessignature.getParameterNames();Object[]argsjoinPoint.getArgs();for(inti0;iparameterNames.length;i){argsMap.put(parameterNames[i],args[i]);}}returnargsMap;}/** * 获取方法注解 */publicstaticTextendsAnnotationTgetMethodAnnotation(JoinPointjoinPoint,ClassTannotationClass){MethodSignaturesignature(MethodSignature)joinPoint.getSignature();Methodmethodsignature.getMethod();returnmethod.getAnnotation(annotationClass);}/** * 获取类注解 */publicstaticTextendsAnnotationTgetClassAnnotation(JoinPointjoinPoint,ClassTannotationClass){Class?targetClassjoinPoint.getTarget().getClass();returntargetClass.getAnnotation(annotationClass);}/** * 获取完整方法路径 */publicstaticStringgetFullMethodName(JoinPointjoinPoint){StringclassNamejoinPoint.getSignature().getDeclaringTypeName();StringmethodNamejoinPoint.getSignature().getName();returnclassName.methodName;}/** * 获取IP地址Web环境下 */publicstaticStringgetIpAddress(JoinPointjoinPoint){try{ServletRequestAttributesattributes(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if(attributes!null){HttpServletRequestrequestattributes.getRequest();returnrequest.getRemoteAddr();}}catch(Exceptione){// 忽略}returnunknown;}}使用示例Before(execution(* com.example.service.*.*(..)))publicvoidbeforeAdvice(JoinPointjoinPoint){// 使用工具类MapString,ObjectargsJoinPointUtils.getArgsMap(joinPoint);StringfullMethodNameJoinPointUtils.getFullMethodName(joinPoint);System.out.println(方法: fullMethodName);System.out.println(参数: args);// 获取特定注解LoglogAnnotationJoinPointUtils.getMethodAnnotation(joinPoint,Log.class);if(logAnnotation!null){System.out.println(日志级别: logAnnotation.level());}}实战场景场景1操作日志记录AspectComponentpublicclassOperationLogAspect{AfterReturning(pointcutannotation(log),returningresult)publicvoidlogOperation(JoinPointjoinPoint,annotation(log)OperationLoglog,Objectresult){// 从连接点获取信息StringmethodNamejoinPoint.getSignature().getName();StringclassNamejoinPoint.getSignature().getDeclaringTypeName();Object[]argsjoinPoint.getArgs();// 构建日志LogRecordrecordLogRecord.builder().module(log.module()).operation(log.operation()).method(className.methodName).params(JSON.toJSONString(args)).result(JSON.toJSONString(result)).ip(JoinPointUtils.getIpAddress(joinPoint)).build();// 保存日志logService.save(record);}}场景2参数验证AspectComponentpublicclassValidationAspect{Before(execution(* com.example.controller.*.*(..)))publicvoidvalidateParams(JoinPointjoinPoint){// 获取所有参数Object[]argsjoinPoint.getArgs();for(Objectarg:args){if(arginstanceofBaseDTO){// 执行DTO验证ValidationResultresultvalidator.validate(arg);if(!result.isValid()){thrownewValidationException(result.getErrors());}}}}}场景3缓存切面AspectComponentpublicclassCacheAspect{Around(annotation(cacheable))publicObjectcacheResult(ProceedingJoinPointjoinPoint,Cacheablecacheable)throwsThrowable{// 生成缓存key类名方法名参数StringkeygenerateCacheKey(joinPoint);// 先从缓存获取Objectcachedcache.get(key);if(cached!null){returncached;}// 执行方法ObjectresultjoinPoint.proceed();// 存入缓存cache.put(key,result,cacheable.ttl(),TimeUnit.SECONDS);returnresult;}privateStringgenerateCacheKey(ProceedingJoinPointjoinPoint){StringBuilderkeynewStringBuilder();// 类名key.append(joinPoint.getSignature().getDeclaringTypeName()).append(.);// 方法名key.append(joinPoint.getSignature().getName()).append(:);// 参数简单处理for(Objectarg:joinPoint.getArgs()){key.append(arg!null?arg.toString():null).append(,);}returnkey.toString();}}⚠️重要限制Spring AOP只支持方法执行连接点// ✅ 支持的Before(execution(* *.*(..)))// ❌ 不支持的需要AspectJBefore(call(* *.*(..)))// 方法调用Before(initialization(*.new(..)))// 构造器Before(get(* *))// 字段读取Before(set(* *))// 字段设置代理机制的影响JDK动态代理只能代理接口方法this和target可能不同CGLIB代理可以代理类this和target通常相同内部方法调用不会被拦截因为不走代理调试技巧打印连接点信息Before(execution(* *.*(..)))publicvoiddebugJoinPoint(JoinPointjoinPoint){System.out.println( JoinPoint信息 );System.out.println(Kind: joinPoint.getKind());System.out.println(Signature: joinPoint.getSignature());System.out.println(SourceLocation: joinPoint.getSourceLocation());System.out.println(StaticPart: joinPoint.getStaticPart());System.out.println();}判断连接点类型Before(execution(* *.*(..)))publicvoidcheckJoinPoint(JoinPointjoinPoint){if(joinPointinstanceofProceedingJoinPoint){System.out.println(这是ProceedingJoinPoint环绕通知可用);}else{System.out.println(这是普通JoinPoint);}}总结连接点的核心要点定义程序执行中可以插入增强的点Spring AOP只支持方法执行这一种连接点JoinPoint对象包含方法签名、参数、目标对象等信息ProceedingJoinPoint用于环绕通知可以控制方法执行一句话记忆连接点就像程序的穴位切入点就是针灸的位置图通知就是扎针的治疗手法。实用口诀连接点执行点方法执行最常见 JoinPoint信息全签名参数都在里边 ProceedingJoinPoint更强可以控制方法执行权 记住Spring有局限只支持方法执行这一个连接点
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

制作网页如何添加图片苏州seo优化

为避免层级、布局和事件体系导致的副作用(例如受父元素的CSS影响) 模态框通常挂在 document.body 或根节点下 直接 DOM 操作 首先我想的是 const modal document.createElement(div) modal.className modal document.body.appendChild(modal)然后配置 …

张小明 2025/12/21 8:48:00 网站建设

塑胶卡板东莞网站建设支持个人兼职网站制作

Plop代码生成器完整开发指南:从入门到精通 【免费下载链接】plop Consistency Made Simple 项目地址: https://gitcode.com/gh_mirrors/pl/plop Plop是一个强大的微生成器框架,专门帮助开发团队以统一、高效的方式生成代码文件和其他文本文件。通…

张小明 2025/12/21 8:43:58 网站建设

济南本地网站建设公司工程公司简介

解锁ab-download-manager隐藏技能:打造智能文件处理自动化插件 【免费下载链接】ab-download-manager A Download Manager that speeds up your downloads 项目地址: https://gitcode.com/GitHub_Trending/ab/ab-download-manager 你是否曾经下载完文件后&am…

张小明 2025/12/21 8:37:53 网站建设

部署wordpress站点巢湖路桥建设集团网站

一、测试工程师整体薪资水平2025年测试工程师的薪资水平呈现明显的岗位分化趋势。根据最新调研数据:高级开发测试工程师‌:月薪区间为20-50K,年薪24-60W,较2024年增长32%,本科平均工资达37.5K 网站测试工程师‌&#x…

张小明 2025/12/21 8:35:51 网站建设