spring boot aop相关使用方式,一般都是使用注解进行配置的,很少使用底层接口进行实现;但是我们如果书写一些公用的sdk,这种方式并不是太友好,所以整理一下 aop 的底层接口,及其使用方式。
增强类型
根据 aop
切入点的不同,我们将切入后执行的代码逻辑成为 增强
,aop联盟
为增强定义了org.aopalliance.aop.Advice
接口;我们接下来看一下 org.aopalliance.aop.Advice
类继承关系
上述所列接口,包含有两部分接口,并且在途中已经标记:
- spring:
spring
定义的扩展增强接口 - aopalliance:
aop联盟
所定义的接口
按照增强在目标类方法连接点的位置可以将增强划分为以下五类:
- 前置增强
org.springframework.aop.BeforeAdvice
:表示在目标方法执行前来实施增强 - 后置增强
org.springframework.aop.AfterReturningAdvice
:
表示在目标方法执行后来实施增强 - 环绕增强
org.aopalliance.intercept.MethodInterceptor
:
表示在目标方法执行前后同时实施增强 - 异常抛出增强
org.springframework.aop.ThrowsAdvice
:表示在目标方法抛出异常后来实施增强 - 引介增强
org.springframework.aop.introductioninterceptor
:
表示在目标类中添加一些新的方法和属性
注意:其中引介增强是一种特殊的增强。它可以在目标类中添加属性和方法,通过拦截定义一个接口,让目标代理实现这个接口。
- 引介增强的连接点是类级别的,而前面的几种则是方法级别的。
- 环绕增强是AOP联盟定义的接口,其他四种增强接口则是Spring定义的接口。
这些增强接口都有一些方法,通过实现这些接口方法,并在接口方法中定义横切逻辑,就可以将它们织入目标类方法的相应连接点位置。
用Spring实现的话: 通过实现这些增强接口,在实现这些接口的方法当中定义横切逻辑,然后通过配置Spring的配置文件就可以完成将增强织入到目标方法当中了。
增强的使用方式
我们在写 sdk
时,不可能使用配置的方式进行配置,所以我们全部使用代码进行配置,这里就以 org.aopalliance.intercept.MethodInterceptor
环绕增强为例,进行使用代码配置。
我们首先需要实现增强方法,即切入点上的逻辑处理:
// 环绕增强
public class MyInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
// TODO 在这里实现我们切入逻辑
return methodInvocation.proceed();
}
}
然后我们使用 spring-boot
的配置方式,进行配置:
/**
* 这里采用包的声明方式,此包下得所有方法,都会得到次增强功能
* @return
*/
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor1() {
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
pointcut.setPattern("com.example.aop.demo.*");
// 配置增强类advisor
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(new MyInterceptor());
System.out.println(advisor.toString());
return advisor;
}
/**
* 采用表达式的方式声明,类似我们在spring-boot中使用切面的方式
* @return
*/
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor2() {
MyInterceptor interceptor = new MyInterceptor();
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
// pointcut.setExpression("execution(* com.example.aop.demo.service..*.*(..))");
// 可以使用注解的方式
pointcut.setExpression("@annotation(com.example.aop.demo.configure.InterceptorAnnotation)");
// 配置增强类advisor
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(interceptor);
return advisor;
}
/**
* 使用注解的方式声明,可以使用表达式进行替代
* @return
*/
@Bean
public Advisor pointcutAdvisor() {
MyInterceptor interceptor = new MyInterceptor();
AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(null, InterceptorAnnotation.class);
// 配置增强类advisor
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(interceptor);
System.out.println(advisor.toString());
return advisor;
}
参考:https://blog.csdn.net/yangshangwei/article/details/77151974