Spring AOP 增强 (Advice)

1. Advice

  • 增强目标类功能,执行一段附加逻辑
  • 接口 org.aopalliance.aop.Advice
package org.aopalliance.aop;
public interface Advice {
}

1.1 引入依赖

org.springframework.bootspring-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
喜欢就支持一下吧
点赞13 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容