AOP中注解参数详解

合集下载

基于SpringBoot、AOP与自定义注解转义字典值

基于SpringBoot、AOP与自定义注解转义字典值

基于SpringBoot、AOP与⾃定义注解转义字典值 ⼀直以来,前端展⽰字典⼀般以中⽂展⽰为主,若在表中存字典值中⽂,当字典表更改字典值对应的中⽂,会造成数据不⼀致,为此设置冗余字段并⾮最优⽅案,若由前端⾃⼰写死转义,不够灵活,若在业务代码转义,臃肿也不够通⽤,从⽹络上了解到注解、AOP是⼀种不错的解决⽅案,主要有两种⽅式: 1、通过注解获取结果集转为JSON字符串,通过正则查找附加字段; 2、通过获取结果集中相关字段上注解,此种⽅法有两个需要解决的问题,⽗类继承字段、嵌合对象难以解决获取对应注解字段问题,解决起来均⽐较⿇烦; 因此本⽂采⽤第⼀种⽅法,能有效规避第⼆种⽅法相关问题,做到逻辑相对简单,引⼊缓存提⾼效率。

⼀、新建注解 标注⽅法上使⽤1 @Retention(RetentionPolicy.RUNTIME)2 @Target(ElementType.METHOD)3 @Documented4public @interface TranslationDict {5 FieldParam[] value();6 } 注解参数:FieldParam1 @Retention(RetentionPolicy.RUNTIME)2 @Target({ElementType.FIELD})3 @Documented4public @interface FieldParam {56/**7 * 字段类型默认字典8 * Constant.FIELDTYPE_DICT 为⾃定义常量9 * @return10*/11int type() default Constant.FIELDTYPE_DICT;1213/**14 * 字典dictType15 * @return16*/17 String dictType() default "";1819/**20 * 要翻译的字段⽬标字段为翻译的字段+Str21 * @return22*/23 String targetField() default "";2425/**26 * 要翻译的字段值类型27 * @return28*/29 Class targetFieldValueClazz() default String.class;3031 }⼆、注解的使⽤ 在需要转义⽅法体上添加注解,在注解上指定需要转义的字段,不声明则使⽤默认值。

AOP标注-实例详解

AOP标注-实例详解

AOP简介AOP(Aspect Orient Programming),也就是面向切面编程,作为面向对象编程的补充。

面向切面编程(AOP)和面向对象编程(OOP)互为补充,面向对象编程将程序分解成各个层次的对象,而面向切面编程将程序运行过程分解成各个切面,可以这样理解,面向对象编程从静态角度考虑程序结构,面向切面编程是从动态角度考虑运行过程。

AOP专门用来处理具有横切性质的系统服务,如事务管理、安全检查、缓存、对象池管理等。

基本概念切面(Aspect):业务流程运行的某个特定步骤,也就是应用运行过程中的关注点,关注点可以横切多个对象,所以常常也称为横切关注点。

连接点(Joinpoint):程序运行过程中明确的点,如方法的调用,或者异常的抛出。

Spring AOP 中,连接点总是方法的调用。

增强处理(Advice):AOP框架在特定在特定的切入点执行的增强处理。

出来有”around”、”before”、”after”等类型。

切入点(Pointcut):可以插入增强处理的连接点。

简而言之,当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。

引入:将方法或者字段添加到被处理的类中。

Spring允许引入新的接口到任何被处理的对象。

目标对象(Target):被AOP框架进行增强处理的对象,也被称为增强的对象。

如果AOP框架是通过运行时代理来实现的,那么这个对象是一个被代理的对象。

AOP代理:AOP框架创建的对象,简单地说代理就是对目标对象的加强。

Spring中的AOP 代理可以是JDK动态代理,也可以是DBLIB代理。

前者为实现接口的目标对象的代理,后者为不实现接口的目标对象的代理。

织入(Weaving):将增强处理添加到目标对象中,并创建一个被增强的对象(AOP代理)的过程就是织入。

织入有两种方式:编译时增强(AspectJ)和运行时增强(DGLIB)。

AOP代理实际是由AOP框架动态生成的一个对象,该对象包含了目标对象全部的方法。

基于注解的Spring AOP的配置和使用

基于注解的Spring AOP的配置和使用

基于注解的Spring AOP的配置和使用AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程。

可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。

AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。

我们现在做的一些非业务,如:日志、事务、安全等都会写在业务代码中(也即是说,这些非业务类横切于业务类),但这些代码往往是重复,复制——粘贴式的代码会给程序的维护带来不便,AOP就实现了把这些业务需求与系统需求分开来做。

这种解决的方式也称代理机制。

先来了解一下AOP的相关概念,《Spring参考手册》中定义了以下几个AOP的重要概念,结合以上代码分析如下:∙切面(Aspect):官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,在本例中,“切面”就是类TestAspect所关注的具体行为,例如,AServiceImpl.barA()的调用就是切面TestAspect所关注的行为之一。

“切面”在ApplicationContext 中<aop:aspect>来配置。

∙连接点(Joinpoint):程序执行过程中的某一行为,例如,UserService.get 的调用或者UserService.delete抛出异常等行为。

∙通知(Advice):“切面”对于某个“连接点”所产生的动作,例如,TestAspect 中对com.spring.service包下所有类的方法进行日志记录的动作就是一个Advice。

其中,一个“切面”可以包含多个“Advice”,例如ServiceAspect。

∙切入点(Pointcut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联。

例如,TestAspect中的所有通知所关注的连接点,都由切入点表达式execution(* com.spring.service.*.*(..))来决定。

(10条消息)springboot自定义注解使用AOP实现请求参数解密以及响应数据加密

(10条消息)springboot自定义注解使用AOP实现请求参数解密以及响应数据加密

(10条消息)springboot⾃定义注解使⽤AOP实现请求参数解密以及响应数据加密⼀、前⾔本篇⽂章将依托与SpringBoot平台,⾃定义注解⽤来标识接⼝请求是否实现加密解密。

使⽤AOP切⾯来具体操作解密加密,实现对源代码的低耦合,不在原基础上做很⼤的改动。

本篇⽂章的所有⽰例,都上传到我的github中,欢迎⼤家拉取测试,欢迎star github实现要求:1. ⾃定义⼀个注解@Secret,⽤来标识需要实现加密解密作⽤在Controller类上,表⽰此Controller类的所有接⼝都实现加密解密作⽤来单⼀⽅法上,表⽰此接⼝⽅法需要实现加密解密2. 使⽤AOP切⾯编程实现在接⼝⽅法执⾏之前将前端的加密参数解密并重新赋给接⼝参数在接⼝⽅法响应之后,将返回的数据进⾏加密返回3. 在配置⽂件中配置,是否开启全局的加密解密操作实现流程:1. 前端请求的接⼝将请求参数json通过AES加密⽣成加密字符串,然后将加密字符串通过名为encyptStr字段传递给后端。

2. AOP前置⽅法拦截,将encyptStr字符串通过AES解密得到原始请求参数json,将json映射为请求⽅法的参数对象User。

3. 接⼝通过参数成功响应,并将响应数据直接返回。

4. AOP后置⽅式拦截,将响应参数data字段⾥的数据AES加密,并返回给前端5. 前端收到请求响应,通过code判断请求是否成功,AES加密data字段得到需要的数据。

⼆、实现操作1. 创建SPRINGBOOT项⽬创建⼀个SpringBoot项⽬,导⼊必要的maven依赖。

使⽤AOP切⾯需要导⼊AOP的启动器lombok是⼀个通过注解简化代码的⼯具,在idea中使⽤需要安装lombok插件json转换⼯具,apache⼯具类pom.xml1. <!-- web依赖 -->2. <dependency>3. <groupId>org.springframework.boot</groupId>4. <artifactId>spring-boot-starter-web</artifactId>5. </dependency>6.7. <!-- AOP切⾯依赖 -->8. <dependency>9. <groupId>org.springframework.boot</groupId>10. <artifactId>spring-boot-starter-aop</artifactId>11. </dependency>12.13. <!-- lombok⼯具 -->14. <dependency>15. <groupId>org.projectlombok</groupId>16. <artifactId>lombok</artifactId>17. <optional>true</optional>18. </dependency>19.20. <!-- json操作类 -->21. <dependency>22. <groupId>com.alibaba</groupId>23. <artifactId>fastjson</artifactId>24. <version>1.2.52.sec06</version>25. </dependency>26. <!-- String⼯具包 -->27. <dependency>28. <groupId>mons</groupId>29. <artifactId>commons-lang3</artifactId>30. <version>3.9</version>31. </dependency>2. ⾃定注解@SECRET我们通过⾃定义的注解,来标识类或接⼝,告诉AOP哪些类或⽅法需要执⾏加密解密操作,更加的灵活。

AOP方法拦截获取参数上的注解

AOP方法拦截获取参数上的注解

AOP⽅法拦截获取参数上的注解获取参数注解在spring aop中,⽆论是前置通知的参数JoinPoint,还是环绕通知的参数ProceedingJoinPoint,都可以通过以下⽅法获得⼊参: MethodSignature signature= (MethodSignature) jp.getSignature();根据源码分析,MethodSignature封装了两个⽅法,⼀个获取⽅法的返回值类型,⼀个是获取封装的Method对象,getReturnType()可以⽤在环绕通知中,我们可以根据这个class类型,做定制化操作.⽽method的参数和参数上的注解,就可以从getMethod()返回的Method对象中拿,api如下:// 获取⽅法上的注解XXX xxx = signature.getMethod().getAnnotation(XXX.class)//获取所有参数上的注解Annotation[][] parameterAnnotations= signature.getMethod().getParameterAnnotations();只有所有的参数注解怎么获取对应参数的值呢?获取所有参数注解返回的是⼀个⼆维数组Annotation[][],每个参数上可能有多个注解,是⼀个⼀维数组,多个参数⼜是⼀维数组,就组成了⼆维数组,所有我们在遍历的时候,第⼀次遍历拿到的数组下标就是⽅法参数的下标,for (Annotation[] parameterAnnotation: parameterAnnotations) {int paramIndex= ArrayUtils.indexOf(parameterAnnotations, parameterAnnotation);}再根据Object[] args= joinPoint.getArgs();拿到所有的参数,根据指定的下标即可拿到对象的值for (Annotation[] parameterAnnotation: parameterAnnotations) {int paramIndex= ArrayUtils.indexOf(parameterAnnotations, parameterAnnotation);for (Annotation annotation: parameterAnnotation) {if (annotation instanceof XXX){Object paramValue = args[paramIndex]}}}通过以上⽅法,即可找到你想要的参数注解,并拿到对应参数的值啦!。

AOP配置(含注解)详解

AOP配置(含注解)详解

AOP配置(含注解)详解AOP(Aspect-Oriented Programming)是面向切面编程的缩写,是一种通过将横切关注点(cross-cutting concern)从业务逻辑代码中分离出来的编程思想和技术。

AOP通过在程序中定义切点(Join point)和通知(Advice),可以在不修改原有代码的情况下,对系统进行横向扩展,实现一些跨越多个对象和模块的功能。

AOP可以通过XML配置或者注解配置来实现,下面将以注解配置为例进行详细解析。

首先,我们需要在项目中引入相关的AOP依赖,如Spring AOP。

然后,我们需要在Spring的配置文件中启用AOP功能,这可以通过在配置文件中添加`<aop:aspectj-autoproxy/>`来实现。

这样,Spring就会自动扫描并自动生成代理类以实现AOP。

接下来,我们需要定义切点和通知。

切点是在程序中定义的一些特定的方法,它们可以被AOP框架所拦截。

通知则是在切点被拦截时执行的一段代码。

除了切面、切点和通知,AOP还涉及到一些其他的概念,如切入点、连接点和增强器。

切入点是一个或多个切点的集合,用于定义一组相关的切点。

连接点是在程序中与切点相匹配的特定位置,如方法的执行点。

增强器则是在通知被调用之前或之后,对连接点进行拦截并执行相应的通知。

总之,AOP通过在程序中定义切点和通知,可以实现对系统中特定方法的拦截和增强。

它可以很好地解耦系统的各个模块,并提供了一种便捷的方式来实现横切关注点的功能。

需要注意的是,AOP是一种非常强大和灵活的编程思想和技术,它可以用于很多方面,如日志记录、性能监控、安全检查等。

在使用AOP时,需要充分考虑系统的复杂性和可维护性,避免过度使用AOP,以免产生不必要的复杂性和难以维护的代码。

同时,需要合理地选择切点和通知,保持代码的简洁和可读性。

SpringAOP切面日志Demo配置文件方式与注解方式

SpringAOP切面日志Demo配置文件方式与注解方式

SpringAOP切⾯⽇志Demo配置⽂件⽅式与注解⽅式⼀、配置⽂件⽅式1、配置applicationContext.xml,<bean id="logAopBean"class="mon.aop.LogAop"></bean><aop:config><aop:aspect id="logAspect"ref="logAopBean"><aop:pointcut expression="execution(* com.demo..*(..))" id="allMethod"/><aop:before method="before" pointcut-ref="allMethod" /><aop:after-throwing method="afterThrowing" pointcut-ref="allMethod" /><aop:after-returning method="afterReturn" pointcut-ref="allMethod" /><aop:after method="after" pointcut-ref="allMethod" /></aop:aspect></aop:config>2、⽇志处理类,/*** LogAop.java** Shanghai NTT DATA Synergy Software Co., Ltd. All Rights Reserved.* @author wyl* @date 2016-10-18*/package mon.aop;import ng.JoinPoint;import ng.ProceedingJoinPoint;/*** @author wyl* @Description TODO* @date 2016-10-18**/public class LogAop {public void before(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println("开始执⾏:"+className+"."+methodName+"()⽅法...");}public void afterThrowing(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法抛出了异常...");}public void afterReturn(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法正常执⾏结束...");}public void after(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()最终执⾏步骤(finally)...");}/*//⽤来做环绕通知的⽅法可以第⼀个参数定义为ng.ProceedingJoinPoint类型public Object doAround(ProceedingJoinPoint call) throws Throwable {Object result = null;this.before(call);//相当于前置通知try {result = call.proceed();this.afterReturn(call); //相当于后置通知} catch (Throwable e) {this.afterThrowing(call); //相当于异常抛出后通知throw e;}finally{this.after(call); //相当于最终通知}return result;}*/}⼆、注解⽅式1、配置applicationContext.xml,<bean id="logAspectBean"class="mon.aop.LogAnnotationAspect"></bean> <aop:aspectj-autoproxy/>2、⽇志处理类,/*** LogAnnotationAspect.java** Shanghai NTT DATA Synergy Software Co., Ltd. All Rights Reserved.* @author wyl* @date 2016-10-18*/package mon.aop;import ng.JoinPoint;import ng.ProceedingJoinPoint;import ng.annotation.After;import ng.annotation.AfterReturning;import ng.annotation.AfterThrowing;import ng.annotation.Aspect;import ng.annotation.Before;import ng.annotation.Pointcut;/*** @author wyl* @Description TODO* @date 2016-10-18**/@Aspect //定义切⾯类public class LogAnnotationAspect {@SuppressWarnings("unused")//定义切⼊点,提供⼀个⽅法,这个⽅法的名字就是改切⼊点的id@Pointcut("execution(* com.demo..*(..))")private void allMethod(){}//针对指定的切⼊点表达式选择的切⼊点应⽤前置通知@Before("allMethod()")public void before(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println("开始执⾏:"+className+"."+methodName+"()⽅法...");}//访问命名切⼊点来应⽤后置通知@AfterReturning("allMethod()")public void afterReturn(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法正常执⾏结束...");}//应⽤最终通知@After("allMethod()")public void after(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()最终执⾏步骤(finally)...");}//应⽤异常抛出后通知@AfterThrowing("allMethod()")public void afterThrowing(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法抛出了异常...");}//应⽤周围通知//@Around("allMethod()")public Object doAround(ProceedingJoinPoint call) throws Throwable{Object result = null;this.before(call);//相当于前置通知try {result = call.proceed();this.afterReturn(call); //相当于后置通知} catch (Throwable e) {this.afterThrowing(call); //相当于异常抛出后通知throw e;}finally{this.after(call); //相当于最终通知}return result;}}。

AOP+自定义注解实现全局参数校验

AOP+自定义注解实现全局参数校验

AOP+⾃定义注解实现全局参数校验AOP+⾃定义注解实现全局参数校验在开发过程中,⽤户传递的数据不⼀定合法,虽然可以通过前端进⾏⼀些校验,但是为了确保程序的安全性,保证数据的合法,在后台进⾏数据校验也是⼗分必要的。

后台的参数校验在controller⽅法中校验:后台的参数是通过controller⽅法获取的,所以最简单的参数校验的⽅法,就是在controller⽅法中进⾏参数校验。

在controller⽅法中如果进⾏参数校验会有⼤量重复、没有太⼤意义的代码。

使⽤拦截器、过滤器校验为了保证controller中的代码有更好的可读性,可以将参数校验的⼯作交由拦截器(Interceptor)或者过滤器(Filter)来完成,但是此时⼜存在⼀个问题:⾮共性的参数需要每个⽅法都创建⼀个与之对应的拦截器(或者过滤器)。

实现对Entity的统⼀校验鉴于上述解决⽅案的缺点,我们可以借助AOP的思想来进⾏统⼀的参数校验。

思想是通过⾃定义注解来完成对实体类属性的标注,在AOP中扫描加了⾃定义注解的属性,对其进⾏注解属性标注的校验。

对于不满⾜的参数直接抛出⾃定义异常,交由全局异常处理来处理并返回友好的提⽰信息。

在介绍此⽅法之前,我们先来介绍⼀下使⽤其会⽤到的⼀些内容。

⾃定义异常在开发过程中,经常需要抛出⼀些异常,但是异常中没有状态码,⾃定义描述等属性。

所以可以⾃定义⼀个异常。

抛出异常时,使⽤全局异常处理,通过全局异常来处理此异常。

注意:Aspect中的异常只有RuntimeException(及其⼦类)能被全局异常处理。

所以我们通常将⾃定义异常定义为运⾏时异常。

package mon.exception;import lombok.*;/*** @Author: rayfoo@* @Date: 2020/7/20 9:26 下午* @Description: ⾃定义的异常...*/@Getter@Setter@Builder@NoArgsConstructor@AllArgsConstructorpublic class MyException extends RuntimeException{private int code;private String msg;}断⾔类在代码的执⾏过程中,我们经常需要在特定条件下(⼀般为是否满⾜某条件)抛出异常,此时需要加⼊抛异常、返回状态码、错误信息、记录⽇志等操作,此操作是⼤量重复的操作,所以借助Junit中Assert的思想,创建了下述的断⾔⼯具类,⽤于在指定条件下抛出⼀个⾃定义异常。

使用spring通过aop获取方法参数和参数值

使用spring通过aop获取方法参数和参数值

使⽤spring通过aop获取⽅法参数和参数值⽬录spring通过aop获取⽅法参数和参数值⾃定义注解切⾯aop切⾯注解、参数获取1、定义需要切⾯的注解2、在需要进⾏切⾯的⽅法标注注解3、定义切⾯spring通过aop获取⽅法参数和参数值⾃定义注解package com.xiaolc.aspect;import ng.annotation.*;/*** @author lc* @date 2019/9/10*/@Documented@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface LiCheng {}切⾯package com.xiaolc.aspect;import ng.ProceedingJoinPoint;import ng.annotation.Around;import ng.annotation.Aspect;import org.springframework.core.DefaultParameterNameDiscoverer;import org.springframework.core.ParameterNameDiscoverer;import ponent;import ng.reflect.Method;import java.util.HashMap;import java.util.Map;/*** 获取⽅法上的注解值*/@Component@Aspectpublic class AuditAnnotationAspect {@Around("@annotation(liCheng))")private static Map getFieldsName(ProceedingJoinPoint joinPoint,LiCheng liCheng) throws ClassNotFoundException, NoSuchMethodException { String classType = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();// 参数值Object[] args = joinPoint.getArgs();Class<?>[] classes = new Class[args.length];for (int k = 0; k < args.length; k++) {if (!args[k].getClass().isPrimitive()) {// 获取的是封装类型⽽不是基础类型String result = args[k].getClass().getName();Class s = map.get(result);classes[k] = s == null ? args[k].getClass() : s;}}ParameterNameDiscoverer pnd = new DefaultParameterNameDiscoverer();// 获取指定的⽅法,第⼆个参数可以不传,但是为了防⽌有重载的现象,还是需要传⼊参数的类型Method method = Class.forName(classType).getMethod(methodName, classes);// 参数名String[] parameterNames = pnd.getParameterNames(method);// 通过map封装参数和参数值HashMap<String, Object> paramMap = new HashMap();for (int i = 0; i < parameterNames.length; i++) {paramMap.put(parameterNames[i], args[i]);System.out.println("参数名:"+parameterNames[i]+"\n参数值"+args[i]);}return paramMap;}private static HashMap<String, Class> map = new HashMap<String, Class>() {{put("ng.Integer", int.class);put("ng.Double", double.class);put("ng.Float", float.class);put("ng.Long", Long.class);put("ng.Short", short.class);put("ng.Boolean", boolean.class);put("ng.Char", char.class);}};}aop切⾯注解、参数获取在⼯作中会经常使⽤aop,这⾥将aop使⽤基本⽅法,获取在切点中使⽤的获取参数、注解做⼀个样例。

Springaop的两种配置方式(XML配置AOP、注解配置AOP)

Springaop的两种配置方式(XML配置AOP、注解配置AOP)

Springaop的两种配置⽅式(XML配置AOP、注解配置AOP)闲来⽆聊对项⽬中⽤到的AOP配置进⾏了⼀下归并。

AOP配置⽅式⼀(XML配置AOP): 1. 编写通知类1/**2 * 通过XML的⽅式配置AOP3*/4public class AspectXmlCheck {5 Logger logger = LoggerFactory.getLogger(AspectXmlCheck.class);67/**8 * 前通知⽅法9 * @param jp 连接点对象10*/11public void beforeCheck(JoinPoint jp) {12 Object[] args = jp.getArgs();13 Stream.of(args).forEach(arg -> {14 ("before: " + (arg == null ? "null" : arg.toString()));15 });16 }1718/**19 * 后通知⽅法20 * @param jp 连接点对象21 * @param retVal 连接点对象执⾏后返回的对象22*/23public void afterCheck(JoinPoint jp, Object retVal) {24 ("after: " + (retVal == null ? "null" : retVal.toString()));25 }2627/**28 * 环绕通知⽅法29 * @param pjp 连接点对象30*/31public Object aroundCheck(ProceedingJoinPoint pjp) {32 Object[] args = pjp.getArgs();33 Stream.of(args).forEach(arg -> {34 ("around before: " + (arg == null ? "null" : arg.toString()));35 });3637 Object proceed = null;38try {39 proceed = pjp.proceed();40 } catch (Throwable throwable) {41 logger.error("around execute error:", throwable);42 }43 ("around after: " + (proceed == null ? "null" : proceed.toString()));4445return proceed;46 }47 } 2. 在spring配置⽂件中引⼊aop标签的命名空间及地址(否则aop标签识不了) 3. 在spring配置⽂件中定义切⾯(execution表达式请⾃⾏脑补) <bean id="aspectXmlCheck" class=".simple.aspect.AspectXmlCheck"/><aop:config><aop:aspect id="myAspectCheck" ref="aspectXmlCheck"><aop:pointcut id="checkPointCut" expression="execution(* .simple.service.SimpleService.doSomething(..))"/><aop:before method="beforeCheck" pointcut-ref="checkPointCut"/><aop:after-returning method="afterCheck" pointcut-ref="checkPointCut" arg-names="jp,retVal" returning="retVal"/><aop:around method="aroundCheck" pointcut-ref="checkPointCut"/></aop:aspect></aop:config>AOP配置⽅式⼆(注解配置AOP): 1. 在spring配置⽂件中引⼊aop标签的命名空间及地址(否则aop标签识不了) 2. 在spring配置⽂件中打开动态代理  <!--使⽤注解配置AOP必须打开如下,否则⽆效,XML配置AOP则⽆需--><!-- 通过aop命名空间的<aop:aspectj-autoproxy />声明⾃动为spring容器中那些配置@aspectJ切⾯的bean创建代理,织⼊切⾯。

N6AOP部分 功能注解

N6AOP部分 功能注解

N6AOP代码工程SopRest,SopBusiness,SopAtomBeanSopRest工程类似于3ge ec-aop-core,ec-roc两个工程。

SopBusiness处理N6现有业务逻辑的工程SopAtomBean是请求和返回的javabean。

我们现有的接口都是一个接口对应两套规范,excel的规范是我们跟上游系统(商城、迷你厅等)规范,word文档的是我们跟下游(北六,cb等)系统的规范。

以流量包订购为例,javabean 存放路径com.ailk.aop.busi.crm.mall.bean.resourcepurchase ResourcePurchaseForMallReq.java对应的就是excel的规范,ResourcePurchaseReq.java对应的就是word文档的规范,我们跟下游系统的规范的javabean需要些一些注解这些注解是为了映射wsdl的字段,业务代码中先拼XML报文,调下游系统的服务现有的两种接口开发方式:1、数据库中配置xml模板td_s_commpara_sop这张表中配置报文模板,用WSCallHelper.getReqXmlOrz(JSONObject comObject,JSONObject baseObject,JSONObject extObject,String reqFunName)方法拼装报文,再用WSClientCaller caller2= new WSClientCaller("UserChgCheck4GSer","CheckUser4GChg"); DataBuf resInfoRet= caller2.call("ZZZZ",XML.toString(objResQureyXml))这个方法调用下游系统服务。

2、使用AtomServiceCaller.callN6Atom(cxt, req,ResourcePurchaseRsp.class)和AtomServiceCaller.callAtomFor4G(cxt, req, ResourcePurchaseRsp.class)两种方法。

AOP详解——精选推荐

AOP详解——精选推荐

AOP详解1、AOP(Aspect Oriented Program):⾯向切⾯编程-通过预编译⽅式和动态代理实现程序功能的统⼀维护的⼀种技术。

降低业务逻辑部分的耦合度,提⾼程序的可重⽤性,提⾼开发效率。

从表⾯上来说,减少了代码的拷贝和对公共⽅法的显⽰调⽤,使⽤aop利⽤切⾯的⽅式实现公共⽅法的调⽤。

2、概念Advice(增强):Advice 定义了在Pointcut⾥⾯定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执⾏的代码。

Pointcut(切点):表⽰⼀组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等⽅式集中起来,它定义了相应的 Advice 将要发⽣的地⽅。

Joint point(连接点):表⽰在程序中明确定义的点,典型的包括⽅法调⽤,对类成员的访问以及异常处理程序块的执⾏等等,它⾃⾝还可以嵌套其它 joint point。

##增强类型AOP联盟为增强定义了 org.aopalliance.aop.Advice接⼝,Spring⽀持五种类型的增强。

带《Spring》标识的接⼝是Spring所定义的扩展增强接⼝,带《aoppaliliance》标识的接⼝是AOP联盟定义的接⼝。

按照增强在⽬标类⽅法中的连接点位置,可以分为以下5类。

1.前置增强2.后置增强3.环绕增强4.异常抛出增强5.引介增强:表⽰在⽬标类中添加⼀些新的⽅法和属性。

这些增强接⼝都有⼀些⽅法,通过实现这些接⼝⽅法,并在接⼝⽅法中定义横切逻辑,就可以为他们织⼊⽬标类⽅法的相应连接点位置。

###前置增强/*** @author kai O'Brian* @create 2020/6/16 22:02*/public interface Waiter {void greetTo(String name);void serveTo(String name);}/*** 天真的服务员只会简单的打招呼和闷头服务* @author kai O'Brian* @create 2020/6/16 22:02*/public class NaiveWaiter implements Waiter {@Overridepublic void greetTo(String name) {System.out.println("greet to "+name);}@Overridepublic void serveTo(String name) {System.out.println("serving to"+name);}}import org.springframework.aop.MethodBeforeAdvice;import ng.reflect.Method;/*** 礼貌⽤语增强* Spring⽬前只提供⽅法调⽤前的前置增强* @author kai O'Brian* @create 2020/6/16 22:05*/public class GreetingBeforeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {String clientName = (String)args[0];System.out.println("How are you ! Mr."+clientName);}}/*** @author kai O'Brian* @create 2020/6/16 22:16*/public class BeforeAdviceTest {public static void main(String[] args) {Waiter target = new NaiveWaiter();GreetingBeforeAdvice advice = new GreetingBeforeAdvice();//1、Spring提供的代理⼯⼚ProxyFactory pf = new ProxyFactory();//2、设置代理⽬标pf.setTarget(target);//3、为⽬标类添加增强pf.addAdvice(advice);//4、⽣成代理类⽣成的为CGLib类型的代理类Waiter proxy = (Waiter) pf.getProxy();proxy.greetTo("liukai");proxy.serveTo("liukai");}}解析ProxyFactoryProxyFactory底层使⽤JDK或CGLib动态代理技术将增强应⽤到⽬标类中。

java aop field注解

java aop field注解

在Java编程中,AOP(面向切面编程)是一种非常有用的编程范式,它可以帮助我们更好地实现代码的解耦和模块化。

在AOP中,Field 注解是一种非常重要的工具,它可以让我们在程序运行的过程中,对类的字段进行增强处理,实现更灵活的编程逻辑。

让我们来了解一下什么是AOP。

AOP是一种编程思想,它的核心思想是通过“横切关注点”的方式来实现系统里各个模块之间的解耦,以及把一些共性的逻辑如日志、事务、权限控制等抽取出来,使得代码更加模块化和可维护。

在Java中,AOP的实现一般有两种方式,一种是基于代理的方式,比如使用Spring AOP;另一种是基于字节码增强的方式,比如使用AspectJ。

无论是哪种方式,都需要对目标类进行增强处理,而Field注解则成为了实现这种增强的重要工具。

接下来,让我们来深入了解一下Field注解。

Field注解可以被用来标记类的字段,以及定义一些业务逻辑。

在AOP中,我们可以利用Field注解来实现对字段的增强操作,比如对字段进行校验、转换、权限控制等。

通过在字段上标记Field注解,我们可以在运行时动态地获取字段的信息,并根据注解定义的逻辑来对字段进行处理。

这种灵活的设计,使得我们可以更好地实现代码的通用性和可维护性。

在实际编程中,Field注解可以被广泛地应用在各个领域。

比如在Web开发中,我们可以使用Field注解来对Controller中的字段进行权限控制;在ORM框架中,我们可以使用Field注解来对实体类的字段进行数据校验和转换;在分布式系统中,我们可以使用Field注解来对服务调用的参数进行校验。

Field注解是一种非常灵活和强大的工具,可以帮助我们更好地实现AOP的编程思想。

回顾本文,我们首先了解了AOP的核心概念和作用,然后深入探讨了Field注解在AOP编程中的重要性和作用。

在文章中,我们多次提及了“Field注解”、“AOP”等关键词,并通过序号标注的方式,对这些关键概念进行了深入的讨论和解释。

aop 切面匹配注解方法的全部子方法

aop 切面匹配注解方法的全部子方法

aop 切面匹配注解方法的全部子方法【标题】AOP切面匹配注解方法的全部子方法【前言】在软件开发领域,AOP(Aspect-Oriented Programming,面向切面编程)作为一种编程范式,旨在将横切关注点(如日志记录、事务管理等)与核心业务逻辑分离,从而提高代码的可重用性和可维护性。

其中,切面匹配注解方法的全部子方法是AOP中的一个重要概念。

本文将从深度和广度两个方面,探究切面匹配注解方法的全部子方法的原理、应用场景和实践技巧。

【目录】1. 切面匹配和注解方法的概念2. AOP框架和切面匹配注解方法的实现原理3. 切面匹配注解方法的应用场景3.1 日志记录3.2 权限控制3.3 缓存管理4. 实践技巧:如何切面匹配注解方法的全部子方法4.1 切面表达式语法4.2 切点和通知的配置4.3 切面匹配的注意事项5. 结论【正文】1. 切面匹配和注解方法的概念切面匹配是AOP中一种重要的技术手段,用于选择哪些连接点(Join Points)将被切面(Aspect)所处理。

而注解方法是在Java编程中,通过注解来标识特定功能或行为的方法。

切面匹配注解方法的全部子方法是指,在AOP中,我们通过切面匹配的方式选择所有调用了某个注解方法的子方法,并对它们进行相应的处理。

2. AOP框架和切面匹配注解方法的实现原理AOP框架提供了丰富的切面匹配方式来选择连接点,其中包括基于切点表达式的方式。

切点表达式使用特定的语法来描述要匹配的连接点,通过匹配注解方法的方式,可以选定其全部子方法。

实现原理上,AOP框架在运行时通过字节码增强或动态代理,动态地将切面代码织入到目标类的方法调用链中,从而实现切面匹配注解方法的全部子方法。

3. 切面匹配注解方法的应用场景3.1 日志记录在日志记录的场景中,我们通常会使用注解来标记关注的方法,比如`@Log`,并希望记录该方法的调用情况以及相关参数。

通过切面匹配注解方法的全部子方法,我们可以在方法执行前后插入相应的日志记录代码,实现全面的日志记录。

SpringAop注解方式参数传递

SpringAop注解方式参数传递

SpringAop注解⽅式参数传递参考原⽂链接:包结构:Spring配置⽂件:Service层⽂件测试类:切⾯⽂件:情景⼀: 注解不包含argNames属性测试结果:分析:情景⼀.1 当增强⽅法上参数名称与arg括号内参数名称不对应时,测试报错;情景⼀.2 当增强⽅法上参数名称对应上,但是类型对应不上时,测试发现增强⽆效;情景⼀.3 当增强⽅法参数名称与类型对应上,但是顺序颠倒时,测试成功情景⼀.4 当增强⽅法参数多余或少于arg内参数时,测试报错情景⼀情况总结: 在没有标注argNames的情况下,arg内参数是按照名称与待增强⽅法(本例中的addUser)对应,顺序随意,且参数个数要符合待增强⽅法; 切⾯中的⽅法⼊参个数以及名称、类型需要与arg内参数相匹配才可以,但是顺序可以打乱;也可以使⽤JoinPoint⽅法获取⼊参(前提是JoinPoint⼀定是第⼀个参数).情景⼆: 注解中包含argNames属性;分析:args()括号内的为按照顺序和待增强⽅法对应,argNames中的为按照名字和args()内对应,⽽切⾯的⽅法⼜和argNames的参数按照顺序对应;情景⼆.1 改变切⾯中⽅法参数,和argNames中参数保持名称不⼀致时,测试成功,可见argNames参数和增强⽅法中参数确实是按照顺序对应,⽽⾮名称对应;情景⼆.2 改变argNames和args()内的参数⽆法按照名称对应上时,测试报错,可见argNames和args()内参数确实按照名称对应.情景⼆.3 改变切⾯增强⽅法⼊参的顺序时,测试发现增强没起作⽤,再次验证了argNames参数和增强⽅法⼊参是按照顺序来对应的;情景⼆.4 JoinPoint⽤法: JointPoint必须放在参数第⼀个,其他位置都会报错,因为底层判断的时候只检查第⼀个参数是否是JoinPoint或者ProceedingJoinPoint或者另⼀种类型;情景三:分析:PointCut注解下⽅法⼊参需要与增强⽅法⼊参⼀致,类型顺序都要⼀样;Pointcut注解args()和argNames不⼀定⾮要都出现;情景三.1切⾯中的⽅法(beginLog)的注解上的test1(a,b)按照顺序和Pointcut中arg()内参数对应,切⾯中的⽅法(beginLog)⼊参和注解上的test1(a,b)⼊参按照名称对应;。

aop中joinpoint获取方法上的注解

aop中joinpoint获取方法上的注解

aop中joinpoint获取方法上的注解在Spring AOP中,你可以使用`JoinPoint`接口来获取方法上的注解。

`JoinPoint`是一个代表方法调用的接口,它提供了许多有用的方法来获取关于调用的信息,包括方法参数、返回值、异常等。

要获取方法上的注解,你可以使用`MethodSignature`接口。

`MethodSignature`接口表示方法的签名,它提供了获取方法名称、参数类型、返回类型和注解的方法。

以下是一个示例代码,演示如何使用`JoinPoint`获取方法上的注解:```javaimport ;import ;import ;public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {// 获取方法签名MethodSignature signature = (MethodSignature) ();// 获取方法上的注解Annotation[] annotations = ().getDeclaredAnnotations();// 遍历注解并处理for (Annotation annotation : annotations) {// 处理注解的逻辑// ...}// 继续执行方法调用return ();}```在上面的代码中,我们首先通过`()`获取方法的签名,然后将其强制转换为`MethodSignature`接口。

接下来,我们使用`getMethod().getDeclaredAnnotations()`方法获取方法上的所有注解。

然后,我们可以遍历注解并执行相应的逻辑。

最后,我们使用`()`继续执行方法的调用。

请注意,上述代码中的示例是使用ProceedingJoinPoint作为参数传递给advice的方法,这表示我们正在编写环绕通知(around advice)。

aop post参数

aop post参数

aop post参数AOP(面向切面编程)是一种编程思想,通过在原有代码逻辑上添加一些横切关注点的处理,使得代码更加模块化、易于维护和扩展。

而在日常的开发中,我们经常需要获取请求参数并进行相应的操作,因此本文将介绍一种基于AOP的获取post请求参数的方法。

在Spring框架中,我们可以通过注解@RequestBody来获取post 请求的参数,但是在一些特殊情况下(比如请求参数不规范、参数较多等),我们需要一种更加灵活的方式来获取参数。

这时,我们可以通过AOP来实现。

首先,我们需要定义一个注解@Param,用来标记需要获取的参数。

代码如下:```@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)public @interface Param {String value() default '';}```然后,在Controller中我们可以使用@Param注解来标记需要获取的参数,代码如下:```@RequestMapping(value = '/example', method =RequestMethod.POST)@ResponseBodypublic String example(@Param('param1') String param1,@Param('param2') String param2) {// do something}```接下来,我们需要编写一个AOP切面来获取请求参数。

代码如下: ```@Aspect@Componentpublic class ParamAspect {@Pointcut('@annotation(com.example.demo.Param)')public void paramPointCut() {}@Around('paramPointCut()')public Object around(ProceedingJoinPoint point) throws Throwable {// 获取requestHttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); // 获取所有参数名称Enumeration<String> paramNames =request.getParameterNames();// 获取方法参数列表MethodSignature signature = (MethodSignature)point.getSignature();String[] parameterNames = signature.getParameterNames(); Object[] args = point.getArgs();// 遍历参数列表,将@Param注解的参数赋值while (paramNames.hasMoreElements()) {String paramName = paramNames.nextElement();String[] paramValues =request.getParameterValues(paramName);for (int i = 0; i < parameterNames.length; i++) {if (parameterNames[i].equals(paramName)) {for (Annotation annotation :signature.getMethod().getParameterAnnotations()[i]) {if (annotation.annotationType() == Param.class) {String value = ((Param) annotation).value();if (StringUtils.isBlank(value)) {args[i] = paramValues[0];} else {args[i] = request.getParameter(value);}break;}}break;}}}// 执行方法return point.proceed(args);}}```最后,我们需要在Spring配置文件中开启AOP支持,代码如下: ```<aop:aspectj-autoproxy />```这样就可以通过AOP来获取post请求的参数了。

SpringAOP如何获取方法参数上的注解

SpringAOP如何获取方法参数上的注解

SpringAOP如何获取⽅法参数上的注解SpringAOP获取⽅法参数上的注解⼀、⽰例①如下代码,⾃定义⼀个参数注解@Test,并将其使⽤到⽅法参数上,⽤于标注需要检验的参数/*** ⾃定义注解,⽤于参数*/@Target(PARAMETER)@Documented@Retention(RetentionPolicy.RUNTIME)public @interface Test{}/*** 接⼝层,使⽤使⽤@Test注解标记参数*/@RestController@RequestMapping("/v1/test")public class TestController {@PostMapping(value = "/email", produces = "application/json")public String send(@RequestBody @Test MailSendDTO mailSendDTO) {//TODO 业务处理return "SUCCESS";}}②通过切⾯拦截该⽅法,从连接点获取signature,并将signature强转为MethodSignature,从⽽从MethodSignature对象可以获取拦截的⽅法对象以及⽅法参数注解@Aspect@Configurationpublic class ValidateAop {/*** 切点配置,表达式,在oxi.test.controller包下,所有的类public的任意参数的⽅法*/@Pointcut("execution(public * oxi.test.controller.*.*(..))")public void validate(){}@Before("validate()")public void doBefore(JoinPoint joinPoint){Object[] params = joinPoint.getArgs();if(params.length == 0){return;}//获取⽅法,此处可将signature强转为MethodSignatureMethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();//参数注解,1维是参数,2维是注解Annotation[][] annotations = method.getParameterAnnotations();for (int i = 0; i < annotations.length; i++) {Object param = params[i];Annotation[] paramAnn = annotations[i];//参数为空,直接下⼀个参数if(param == null || paramAnn.length == 0){continue;}for (Annotation annotation : paramAnn) {//这⾥判断当前注解是否为Test.classif(annotation.annotationType().equals(Test.class)){//校验该参数,验证⼀次退出该注解//TODO 校验参数break;}}}}}⼆、debug通过debug代码:可发现连接点实际为MethodInvocationProceedingJoinPoint对象,连接点中的signature则为MethodSignatureImpl对象,是MethodInvocationProceedingJoinPoint的内部类。

AOP中注解参数详解

AOP中注解参数详解

AOP编程中注解参数详解@Pointcut("execution(* transfer(..))")private void anyOldTransfer() {}切入点指定者的支持Spring AOP 支持在切入点表达式中使用如下的AspectJ切入点指定者:1:execution:匹配方法执行的连接点,这是你将会用到的Spring的最主要的切入点指定者。

2:within:限定匹配特定类型的连接点(在使用Spring AOP的时候,在匹配的类型中定义的方法的执行)。

3:this:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中bean reference (Spring AOP 代理)是指定类型的实例。

4: target:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中目标对象(被代理的appolication object)是指定类型的实例。

5: args:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中参数是指定类型的实例。

6: @target:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中执行的对象的类已经有指定类型的注解。

7: @args:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中实际传入参数的运行时类型有指定类型的注解。

8: @within:限定匹配特定的连接点,其中连接点所在类型已指定注解(在使用Spring AOP 的时候,所执行的方法所在类型已指定注解)。

9: @annotation:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中连接点的主题有某种给定的注解合并切入点表达式切入点表达式可以使用‘&&', '||' 和 '!'来合并.还可以通过名字来指向切入点表达式。

Springboot自定义注解+AOP实现参数不能为空

Springboot自定义注解+AOP实现参数不能为空

Springboot⾃定义注解+AOP实现参数不能为空⼀:⾃定义注解类1package com.wing.my.cloud.system.modular.system.util.annotation;23import ng.annotation.*;45 @Target({ElementType.PARAMETER, ElementType.METHOD})6 @Retention(RetentionPolicy.RUNTIME)7 @Documented8public @interface CheckNullParams {9 String[] params();10 }View Code⼆:AOP1package com.wing.my.cloud.system.modular.system.util.aspect;23import com.alibaba.fastjson.JSON;4import com.alibaba.fastjson.JSONObject;5import com.alibaba.fastjson.serializer.SerializerFeature;6import com.wing.my.cloud.kernel.model.exception.ServiceException;7import com.wing.my.cloud.system.modular.system.util.annotation.CheckNullParams;8import lombok.extern.slf4j.Slf4j;9import ng.ProceedingJoinPoint;10import ng.annotation.Around;11import ng.annotation.Aspect;12import ng.annotation.Pointcut;13import ng.reflect.MethodSignature;14import ponent;15import org.springframework.util.StringUtils;16import org.springframework.web.context.request.RequestContextHolder;17import org.springframework.web.context.request.ServletRequestAttributes;1819import javax.servlet.http.HttpServletRequest;20import java.util.*;2122/**23 * 校验参数不能为空24 * ProceedingJoinPoint只能⽤在环绕通知上。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

AOP编程中注解参数详解@Pointcut("execution(* transfer(..))")private void anyOldTransfer() {}切入点指定者的支持Spring AOP 支持在切入点表达式中使用如下的AspectJ切入点指定者:1:execution:匹配方法执行的连接点,这是你将会用到的Spring的最主要的切入点指定者。

2:within:限定匹配特定类型的连接点(在使用Spring AOP的时候,在匹配的类型中定义的方法的执行)。

3:this:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中bean reference (Spring AOP 代理)是指定类型的实例。

4: target:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中目标对象(被代理的appolication object)是指定类型的实例。

5: args:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中参数是指定类型的实例。

6: @target:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中执行的对象的类已经有指定类型的注解。

7: @args:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中实际传入参数的运行时类型有指定类型的注解。

8: @within:限定匹配特定的连接点,其中连接点所在类型已指定注解(在使用Spring AOP 的时候,所执行的方法所在类型已指定注解)。

9: @annotation:限定匹配特定的连接点(使用Spring AOP的时候方法的执行),其中连接点的主题有某种给定的注解合并切入点表达式切入点表达式可以使用‘&&', '||' 和 '!'来合并.还可以通过名字来指向切入点表达式。

切入点表达式的基本语法Spring AOP 用户可能会经常使用 execution pointcut designator。

执行表达式的格式如下:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)除了返回类型模式(上面代码片断中的ret-type-pattern),名字模式和参数模式以外,所有的部分都是可选的。

返回类型模式决定了方法的返回类型必须依次匹配一个连接点。

类型匹配模式1:*:匹配任何数量字符;比如模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型2:..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数,可以使零到多个。

3: +:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。

类型匹配模式示例1:ng.String 匹配String类型;2:java.*.String 匹配java包下的任何“一级子包”下的String类型;如匹配ng.String,但不匹配ng.ss.String3:java..* 匹配java包及任何子包下的任何类型;如匹配ng.String、ng.annotation.Annotation4:ng.*ing 匹配任何ng包下的以ing结尾的类型;5:ng.Number+ 匹配ng包下的任何Number的子类型;如匹配ng.Integer,也匹配java.math.BigInteger切入点表达式的基本示例,使用execution1:public * *(..)任何公共方法的执行2:* cn.javass..IPointcutService.*()cn.javass包及所有子包下IPointcutService接口中的任何无参方法3:* cn.javass..*.*(..)cn.javass包及所有子包下任何类的任何方法4:* cn.javass..IPointcutService.*(*)cn.javass包及所有子包下IPointcutService接口的任何只有一个参数方法5:* (!cn.javass..IPointcutService+).*(..)非“cn.javass包及所有子包下IPointcutService接口及子类型”的任何方法6:* cn.javass..IPointcutService+.*()cn.javass包及所有子包下IPointcutService接口及子类型的的任何无参方法7:* cn.javass..IPointcut*.test*(java.util.Date)cn.javass包及所有子包下IPointcut前缀类型的的以test开头的只有一个参数类型为java.util.Date的方法,注意该匹配是根据方法签名的参数类型进行匹配的,而不是根据执行时传入的参数类型决定的如定义方法:public void test(Object obj);即使执行时传入java.util.Date,也不会匹配的。

8:* cn.javass..IPointcut*.test*(..) throws IllegalArgumentException, ArrayIndexOutOfBoundsExceptioncn.javass包及所有子包下IPointcut前缀类型的的任何方法,且抛出IllegalArgumentException和ArrayIndexOutOfBoundsException异常9:* (cn.javass..IPointcutService+ && java.io.Serializable+).*(..)任何实现了cn.javass包及所有子包下IPointcutService接口和java.io.Serializable接口的类型的任何方法10:@ng.Deprecated * *(..)任何持有@ng.Deprecated注解的方法11:@ng.Deprecated @cn.javass..Secure * *(..)任何持有@ng.Deprecated和@cn.javass..Secure注解的方法12:@(ng.Deprecated || cn.javass..Secure) * *(..)任何持有@ng.Deprecated或@ cn.javass..Secure注解的方法13:(@cn.javass..Secure *) *(..)任何返回值类型持有@cn.javass..Secure的方法14:* (@cn.javass..Secure *).*(..)任何定义方法的类型持有@cn.javass..Secure的方法15:* *(@cn.javass..Secure (*) , @cn.javass..Secure (*))任何签名带有两个参数的方法,且这个两个参数都被@ Secure标记了,如public void test(@Secure String str1, @Secure String str1);16:* *((@ cn.javass..Secure *))或* *(@ cn.javass..Secure *)任何带有一个参数的方法,且该参数类型持有@ cn.javass..Secure;如public voidtest(Model model);且Model类上持有@Secure注解17:* *(@cn.javass..Secure (@cn.javass..Secure *) ,@ cn.javass..Secure(@cn.javass..Secure *))任何带有两个参数的方法,且这两个参数都被@ cn.javass..Secure标记了;且这两个参数的类型上都持有@ cn.javass..Secure;18:* *(java.util.Map<cn.javass..Model, cn.javass..Model>, ..)任何带有一个java.util.Map参数的方法,且该参数类型是以<cn.javass..Model,cn.javass..Model>为泛型参数;注意只匹配第一个参数为java.util.Map,不包括子类型;如public void test(HashMap<Model, Model> map, String str);将不匹配,必须使用“* *(java.util.HashMap<cn.javass..Model,cn.javass..Model>, ..)”进行匹配;而public void test(Map map, int i);也将不匹配,因为泛型参数不匹配19:* *(java.util.Collection<@cn.javass..Secure *>)任何带有一个参数(类型为java.util.Collection)的方法,且该参数类型是有一个泛型参数,该泛型参数类型上持有@cn.javass..Secure注解;如public voidtest(Collection<Model> collection);Model类型上持有@cn.javass..Secure切入点表达式的基本示例,使用within匹配指定类型内的方法1:within(cn.javass..*)cn.javass包及子包下的任何方法执行2:within(cn.javass..IPointcutService+)cn.javass包或所有子包下IPointcutService类型及子类型的任何方法3:within(@cn.javass..Secure *)持有cn.javass..Secure注解的任何类型的任何方法必须是在目标对象上声明这个注解,在接口上声明的对它不起作用切入点表达式的基本示例,使用this使用“this(类型全限定名)”匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口方法也可以匹配;注意this中使用的表达式必须是类型全限定名,不支持通配符1:this(cn.javass.spring.chapter6.service.IPointcutService)当前AOP对象实现了 IPointcutService接口的任何方法2:this(cn.javass.spring.chapter6.service.IIntroductionService)当前AOP对象实现了 IIntroductionService接口的任何方法也可能是引入接口切入点表达式的基本示例,使用target使用“target(类型全限定名)”匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;注意target中使用的表达式必须是类型全限定名,不支持通配符1:target(cn.javass.spring.chapter6.service.IPointcutService)当前目标对象(非AOP对象)实现了 IPointcutService接口的任何方法2:target(cn.javass.spring.chapter6.service.IIntroductionService)当前目标对象(非AOP对象)实现了IIntroductionService 接口的任何方法不可能是引入接口切入点表达式的基本示例,使用args使用“args(参数类型列表)”匹配当前执行的方法传入的参数为指定类型的执行方法;注意是匹配传入的参数类型,不是匹配方法签名的参数类型;参数类型列表中的参数必须是类型全限定名,通配符不支持;args属于动态切入点,这种切入点开销非常大,非特殊情况最好不要使用1:args (java.io.Serializable,..)任何一个以接受“传入参数类型为 java.io.Serializable”开头,且其后可跟任意个任意类型的参数的方法执行,args指定的参数类型是在运行时动态匹配的切入点表达式的基本示例,使用@within使用“@within(注解类型)”匹配所以持有指定注解类型内的方法;注解类型也必须是全限定类型名1:@within cn.javass.spring.chapter6.Secure)任何目标对象对应的类型持有Secure注解的类方法;必须是在目标对象上声明这个注解,在接口上声明的对它不起作用切入点表达式的基本示例,使用@target使用“@target(注解类型)”匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;注解类型也必须是全限定类型名1:@target (cn.javass.spring.chapter6.Secure)任何目标对象持有Secure注解的类方法;必须是在目标对象上声明这个注解,在接口上声明的对它不起作用切入点表达式的基本示例,使用@args使用“@args(注解列表)”匹配当前执行的方法传入的参数持有指定注解的执行;注解类型也必须是全限定类型名1:@args (cn.javass.spring.chapter6.Secure)任何一个只接受一个参数的方法,且方法运行时传入的参数持有注解cn.javass.spring.chapter6.Secure;动态切入点,类似于arg指示符;切入点表达式的基本示例,使用@annotation使用“@annotation(注解类型)”匹配当前执行方法持有指定注解的方法;注解类型也必须是全限定类型名1:@annotation(cn.javass.spring.chapter6.Secure )当前执行方法上持有注解 cn.javass.spring.chapter6.Secure将被匹配切入点表达式的基本示例,使用bean使用“bean(Bean id或名字通配符)”匹配特定名称的Bean对象的执行方法;Spring AOP 扩展的,在AspectJ中无相应概念1:bean(*Service)匹配所有以Service命名(id或name)结尾的Bean切入点表达式的基本示例,使用reference pointcut引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持,如下所示:java代码:查看复制到剪贴板打印@Pointcut(value="bean(*Service)") //命名切入点1private void pointcut1(){}@Pointcut(value="@args(cn.javass.spring.chapter6.Secure)") //命名切入点2 private void pointcut2(){}@Before(value = "pointcut1() && pointcut2()") //引用命名切入点public void referencePointcutTest1(JoinPoint jp) {dump("pointcut1() && pointcut2()", jp);}声明通知通知是跟一个切入点表达式关联起来的,并且在切入点匹配的方法执行之前或者之后或者之前和之后运行。

相关文档
最新文档