AOP(Aspect Oriented Programming)是基于切面编程的,可无侵入的在原本功能的切面层添加自定义代码,一般用于日志收集、权限认证等场景。

AOP基本概念

  通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理;

Before :前置通知,在连接点方法前调用;对应Spring中@Before注解;
After :后置通知,在连接点方法后调用;对应Spring中的@After注解;
AfterReturning:返回通知,在连接点方法执行并正常返回后调用,要求连接点方法在执行过程中没有发生异常;对应Spring中的@AfterReturning注解;
AfterThrowing:异常通知,当连接点方法异常时调用;对应Spring中的@AfterThrowing注解;
Around:环绕通知,它将覆盖原有方法,但是允许你通过反射调用原有方法;对应Spring中的@Around注解;

  连接点(Join Point): 连接点表示应用执行过程中能够插入切面的一个点。在 Spring AOP 中,连接点总是方法的调用,可以说目标对象中的方法就是一个连接点;
  切点(Pointcut): 就是连接点的集合;对应Spring中的@Pointcut注解;

目前Spring支持的切点匹配表达式主要有以下几种:
execution:可以定义到的最小粒度是方法,修饰符,包名,类名,方法名,Spring AOP主要也是使用这个匹配表达式;
within:只能定义到类;例如@Pointcut(within(com.jnu.example.*))
this:当前生成的代理对象的类型匹配;
target:目标对象类型匹配;
annotation:针对注解;
args:只针对参数;

例如: execution (* com.sample.service..*. *(..)) 整个表达式可以分为五个部分:
1、execution()::表达式主体;
2、第一个*号:表示返回类型, *号表示所有的类型;
3、包名:表示需要拦截的包名,包名后面的..,表明com.sample.service包、及其子包;
4、第二个*号:表示类名,*号表示所有的类;
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个点表示任何参数; 

  切面(Aspect): 切面是通知和切点的结合;对应Spring中的注解@Aspect修饰的一个类;
  目标对象(Target object):即被代理的对象;    
  代理对象(AOP proxy):包含了目标对象的代码和增强后的代码的那个对象;

   自定义注解实例可以参见:注解

@EnableAspectJAutoProxy分析

  在spring-boot-autoconfigure-**.jar中,有个配置类,来控制AOP功能的开启和关闭:

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(Advice.class)
    static class AspectJAutoProxyingConfiguration {

        @Configuration(proxyBeanMethods = false)
        @EnableAspectJAutoProxy(proxyTargetClass = false)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
                matchIfMissing = false)
        static class JdkDynamicAutoProxyConfiguration {

        }

        @Configuration(proxyBeanMethods = false)
        @EnableAspectJAutoProxy(proxyTargetClass = true)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
                matchIfMissing = true)
        static class CglibAutoProxyConfiguration {

        }

    }

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingClass("org.aspectj.weaver.Advice")
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
            matchIfMissing = true)
    static class ClassProxyingConfiguration {

        ClassProxyingConfiguration(BeanFactory beanFactory) {
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
        }

    }

}
AopAutoConfiguration

相关文章:

  • 2021-12-29
  • 2021-07-14
  • 2021-10-25
  • 2021-09-16
  • 2021-05-27
  • 2018-06-20
  • 2021-05-19
  • 2021-07-24
猜你喜欢
  • 2021-11-04
  • 2021-06-18
  • 2021-07-15
  • 2022-12-23
  • 2022-01-02
  • 2021-07-28
  • 2021-11-30
相关资源
相似解决方案