Spring AOP 增强 (Advice)

2023-12-13  本文已影响0人  Tinyspot

1. Advice

package org.aopalliance.aop;
public interface Advice {
}

1.1 引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

1.2 增强类型

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)

// 此类还有问题,待定
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) {}
}
上一篇 下一篇

猜你喜欢

热点阅读