1. Advice
- 增强目标类功能,执行一段附加逻辑
- 接口
org.aopalliance.aop.Advice
package org.aopalliance.aop;
public interface Advice {
}
1.1 引入依赖
org.springframework.boot spring-boot-starter-aop
1.2 增强类型
- 前置增强 (MethodBeforAdvice)
- 后置增强 (AfterReturningAdvice)
- 环绕增强 (MethodInterceptor)
- 异常抛出增强 (ThrowsAdvice)
- 引介增强 (IntroductionInterceptor)
2.1 前置增强 (MethodBeforAdvice)
public class MyInterceptorBefore implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("MyInterceptorBefore: " + target.getClass() + "; " + method.getName() + "; " + JSON.toJSONString(args));
}
}
2.2 后置增强 (AfterReturningAdvice)
public class MyInterceptorAfter implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("MyInterceptorAfter: " + target.getClass() + "; " + method.getName() + "; " +JSON.toJSONString(args));
}
}
2.3 环绕增强 (MethodInterceptor)
- 方法拦截器,在方法的前后实施操作
public class MyInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("MyInterceptor: " + invocation.getThis().getClass() + "; " + invocation.getMethod().getName());
return invocation.proceed();
}
}
2.4 引介增强 (IntroductionInterceptor)
- 前面的增强都是作用于方法,引介增强作用于类;引介增强可以在目标类中添加一些新的方法和属性
- 通过扩展 DelegatingIntroductionInterceptor 来实现引介增强
// 此类还有问题,待定
public class MyInterceptorIntroduction implements IntroductionInterceptor, CustomService {
@Nullable
@Override
public Object invoke(@NotNull MethodInvocation invocation) throws Throwable {
if (implementsInterface(invocation.getMethod().getDeclaringClass())) {
return invocation.getMethod().invoke(this, invocation.getArguments());
}
return invocation.proceed();
}
@Override
public boolean implementsInterface(Class> intf) {
return intf.isAssignableFrom(this.getClass());
}
@Override
public String introduce() {
System.out.println("MyInterceptorIntroduction...");
return "This is my introduce";
}
}
public interface CustomService {
String introduce();
}
3. 自定义增强类 Advisor
@Slf4j
public class MyInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
log.info(this.getClass().getSimpleName() + "; " + invocation.getThis().getClass().getSimpleName() + "; "
+ invocation.getMethod().getName());
return invocation.proceed();
}
}
3.1 类/方法拦截方式
@Configuration
public class MyInterceptorConfig {
public static final String execution = "execution(* com.example.concrete.starter.service.*.*(..))";
@Bean
public Advisor defaultPointcutAdvisor() {
MyInterceptor myInterceptor = new MyInterceptor();
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(execution);
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
advisor.setPointcut(pointcut);
advisor.setAdvice(myInterceptor);
return advisor;
}
}
3.2 注解拦截方式
自定义注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InterceptAnno {
}
方式一:拦截类
@Configuration
public class MyInterceptorConfig {
@Bean
public Advisor pointcutAdvisor() {
MyInterceptor myInterceptor = new MyInterceptor();
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(InterceptAnno.class, true);
advisor.setPointcut(pointcut);
advisor.setAdvice(myInterceptor);
return advisor;
}
}
@InterceptAnno
public interface GreetService {
String greeting();
}
方式二:拦截方法
public interface GreetService {
@InterceptAnno
String greeting();
}
@Configuration
public class MyInterceptorConfig {
@Bean
public Advisor pointcutAdvisor() {
MyInterceptor myInterceptor = new MyInterceptor();
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(null, InterceptAnno.class, true);
advisor.setPointcut(pointcut);
advisor.setAdvice(myInterceptor);
return advisor;
}
}
注意 checkInherited 参数,默认是 false, 注解需要加在实现类里
设置为true时,注解可加在接口上
源码如下:
public class AnnotationMatchingPointcut implements Pointcut {
public AnnotationMatchingPointcut(@Nullable Class extends Annotation> classAnnotationType,
@Nullable Class extends Annotation> methodAnnotationType) {
this(classAnnotationType, methodAnnotationType, false);
}
public AnnotationMatchingPointcut(@Nullable Class extends Annotation> classAnnotationType,
@Nullable Class extends Annotation> methodAnnotationType, boolean checkInherited) {}
}
【信息由网络或者个人提供,如有涉及版权请联系COOY资源网邮箱处理】
© 版权声明
部分内容为互联网分享,若有侵权请联系站长删除。
THE END
暂无评论内容