AOP实战分享——简单注解联动和方法前后参数修改
作者:互联网
在实战开始之前,先进行简单的配套说明,既然是注释相关,那么肯定要对注释有一定的说明:
对注释有了解的可以直接略过。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Authorize {
String paramater() default "id"; // 参数名称,默认参数名id
}
上面是一个简单的例子,使用了简单的注释,其中@Target方法用于定义注释使用的位置,上面的ElementType.METHOD对应的是方法,也就是在方法上使用注释,其从名称METHOD可以简单的看出。其余相关方法图示一览:
@Retention注解用于编译时的预操作,这里我们选择RetentionPolicy.RUNTIME,对应参与JVM运算,可以理解为运行时,以下为源码分类一览:
@Documented 是javadoc相关,在使用后,根据是否使用注解,来区分是否出来在生成的文档中
以上都是注解的简单使用和说明,理解了上面的说明后,我们来看AOP对注解的切入使用,这种使用可以尽量做到低耦合,甚至无耦合。
@Aspect
@Component
@Slf4j
@Order(3) // 这里定义执行顺序,值越小越先执行,执行可以看成是一个同心圆,around前的先执行,around后的后执行
public class AuthorizeAcpect {
/**
* 定义切入点
*/
@Pointcut("@annotation(xxx.xxx.annotation.Authorize)")
public void authorize() {
}
@Around("authorize()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature methodSignature = (MethodSignature) point.getSignature();
Method method = methodSignature.getMethod();
String[] parameterNames = methodSignature.getParameterNames();
Authorize annotation = method.getAnnotation(Authorize.class);
int indexParamater = ArrayUtils.indexOf(parameterNames, annotation.paramater()); // paramater对应参数名,请直接将参数名传入
Object[] args = point.getArgs();
Integer id = (Integer) args[indexParamater]; // Id获取Integer写死,毕竟传入的参数类型
// 处理id如设定id = 6
Integer refId = 6;
args[indexParamater] = refId;
Object object = point.proceed(args); // 执行方法
// 了解返回值的实体类或者 instanceof
if (object instanceof Integer) {
return id; // 返回
}
return object;
}
}
@Aspect
@Component
这两个注解对应Spring AOP、Spring Boot,如果你使用的Spring,那么请老老实实地在XML配置AOP
@Order(3) // 用于定义执行顺序,其中越小圈在外面也就越早执行,多个AOP则是一个同心圆,其中圆心是方法执行
MethodSignature methodSignature = (MethodSignature) point.getSignature();
Method method = methodSignature.getMethod();
String[] parameterNames = methodSignature.getParameterNames();
是写死的获取参数列表的方法,同时保证了参数的顺序,因此,可以通过判断参数列表的位置,来判断args[]里面的值的位置
annotation.paramater()为写在注解中的参数名称,这就能通过上面的参数列表,计算出参数所在的位置
int indexParamater = ArrayUtils.indexOf(parameterNames, annotation.paramater()); // 获取参数Id所在位置
计算方法如上,这个ArrayUtils 我看了一下是package org.apache.commons.lang 我觉得这个应该是大家都在使用的工具包就不详谈了
Object[] args = point.getArgs();
此为使AOP内方法进行执行状态,在执行完成后的值则会返回到object,同时这也意味着方法执行后可以进行再次进行修改
if (object instanceof Integer) {
return id; // 返回
}
这里模仿了对参数的修改,当是Integer类型时,直接返回之前获取的修改前的值
这就保证了参数传入Id,id自动转换为6,业务方面用6操作,返回后,6再次转换为原id的Aop处理
这使用了AOP保证了Id的转换在业务中0耦合,当然实际业务肯定更加复杂,这里将复杂的业务进行了简单的替换,在实际业务中当然也可以追求0耦合,但是也要灵活操作,部分时候,可以灵活传入key值,通过key值,较少耦合完成需求
以上是很简单的AOP使用,当然为了保证水平较差的同学也能理解,多废了一些口舌,否则我相信直接贴上代码,说几句使用心得就行了
如果有太啰嗦请进行指正,同时也希望有路过的大佬,有更精巧的心得,一并分享出来,一起讨论,期待和大佬思想和代码层面的交流。
标签:args,AOP,参数,联动,注解,Integer,methodSignature,id 来源: https://blog.csdn.net/qq_37231207/article/details/104612217