美文网首页
Spring AOP 增强 (Advice)

Spring AOP 增强 (Advice)

作者: Tinyspot | 来源:发表于2023-12-13 17:46 被阅读0次

1. Advice

  • 增强目标类功能,执行一段附加逻辑
  • 接口 org.aopalliance.aop.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 增强类型

  • 前置增强 (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) {}
}

相关文章

  • Spring AOP 代理

    Spring AOP 代理 1. Spring AOP 增强类型 AOP 联盟为通知 Advice 定义了 org...

  • Spring AOP

    Spring AOP 一、面向切面编程 1. AOP术语 1.1 ADVICE(增强) Spring提供了以下几种...

  • Spring AOP增强(Advice)

    Sring AOP通过PointCut来指定在那些类的那些方法上织入横切逻辑,通过Advice来指定在切点上具体做...

  • Spring与设计模式

    适配器模式 在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能。每个类型Advice都有对应...

  • Spring之AOP

    Spring之AOP 第二步:增强(advice) 第三:在applicationContext.xml中进行配置...

  • Spring一般切面

    Spring一般切面 Spring 实现了AOP联盟Advice这个接口=>org.aopalliance.aop...

  • Sping - AOP - Advice

    原文地址:https://mkyong.com/spring/spring-aop-examples-advice...

  • 03 AOP学习之五种通知

    Spring AOP五种通知详解 spring aop通知(advice)分成五类: 前置通知Before adv...

  • AOP的基本术语

    通知、增强(Advice) 通知就是你想要的功能,在特定的连接点,AOP框架执行的动作。Spring切面可以应用5...

  • 笔试题 计算机

    spring aop通知(advice)分成五类:前置通知[Before advice]:在连接点前面执行,前置通...

网友评论

      本文标题:Spring AOP 增强 (Advice)

      本文链接:https://www.haomeiwen.com/subject/brtigdtx.html