Spring@EnableAspectJAutoProxy注解AOP源码解析

本文详细介绍了Spring AOP的原理、不同实现方式(基于代理的SpringAOP、Aspectj和Pojo切面),并展示了如何通过@EnableAspectJAutoProxy进行配置和使用,包括前置、后置、返回和异常通知。
摘要由CSDN通过智能技术生成

一、AOP简介
Spring AOP 模块提供了一个符合AOP联盟标准的面相切面编程的实现,它让你可以订阅例如方法拦截器和切点
,从而将逻辑代码分开,简单它们之间的耦合性。AOP可以让一组类共享相同的行为。Spring只支持方法级别的连接点
Spring 提供了4种类型的AOP支持
 1、基于代理的Spring AOP
 2、纯粹Pojo切面
 3、@Aspect驱动的切面
 4、注入式的Aspectj的切面
前三种都是Spring Aop实现的变体,Spring Aop构建在动态代理之上,因此Spring Aop局限于方法拦截。
1、Spring Aop 和Aspectj的关系
Aspectj是一套Aop框架,对java语言和语义的扩展。他自己提供了一套关键字,没有安装Aspectj的情况下
无法使用Aspectj。而Spring Aop 依赖的是Spring,仅仅能做到方法级别拦截,所以在Spring使用@Aspectj注解
实现的Aop功能,底层实现还是Spring Aop。Spring缺省使用J2SE动态代理,这样任何接口都可以被代理,也可以使用
CGLIB代理,对于需要代理类不是接口的时候默认使用CGLIB代理。Spring使用了和Aspectj一样的注解,并使用
Aspectj来做切入点解析和匹配,但是Spring Aop运行时仍旧是纯Spring Aop,不依赖Aspectj的编译器或者织入器
2、@EnableAspectJAutoProxy注解使用步骤
  1、导入aop模块;Spring AOP:(spring-aspects)
  2、定义一个业务逻辑类(MathCalculator);在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)
  3、定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator.div运行到哪里然后执行;
          通知方法:
              前置通知(@Before):logStart:在目标方法(div)运行之前运行
              后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还是异常结束)
              返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行
              异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
              环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())
  4、给切面类的目标方法标注何时何地运行(通知注解)
  5、将切面类和业务逻辑类(目标方法所在类)都加入到容器中
  6、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
  7、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】
3、@EnableAspectJAutoProxy注解原理
  1、利用@Import向容器中导入AspectJAutoProxyRegistrar组件
   AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,通过重新registerBeanDefinitions方法向容器中注册BeanDefinetion
   名称internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
  2、AnnotationAwareAspectJAutoProxyCreator 
     实现了一系列Aware接口,在Bean装载的时候获取BeanFactory,Bean的ClassLoader,实现了Order接口,继承了
     PorxyConfig,ProxyConfig中主要封装了代理的通用处理逻辑,比如设置目标类,设置使用cglib还是java proxy等一些基础配置
      ->AspectJAwareAdvisorAutoProxyCreator
        公开了Aspectj的调用上下文,并弄清楚来自同一切面的多个Advisor在Aspectj中的优先级规则。
        ->AbstractAdvisorAutoProxyCreator
          通用自动代理创建器,它基于检查到的每个顾问程序为特定的Bean构建Aop代理。
          ->AbstractAutoProxyCreator 主要抽象了实现代理的逻辑,就相当于一个代理创建的模版,规定了一些步骤。获取Advisor的
             扩展了 ProxyProcessorSupport,实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口
             是BeanPostProcessor 实现,该实现使用AOP代理包装每个合格的bean,并在调用bean本身之前委派给指定的拦截器
            ->implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
              关注后置处理器(在bean初始化完成前后做事情)、自动装配BeanFactory
  流程:
        1)、传入配置类,创建Ioc容器
        2)、注册配置类,AnnotationConfigApplicationContext构造方法调用refresh()刷新容器
        3)、AbstractApplicationContext 中 registerBeanPostProcessors(beanFactory)注册Bean的后置处理器方便拦截Bean的创建
          1)、先获取Ioc容器中已经定义需要创建的所有BeanPostProcessor
          2)、给容器增加其他BeanPostProcessor(BeanPostProcessorChecker、ApplicationListenerDetector)
          3)、优先注册实现了PriorityOrdered接口的BeanPostProcessor
          4)、再给容器中注册实现了Ordered接口的BeanPostProcessor
          5)、最后注册没有实现优先级接口的BeanPostProcessor
          6)、getBean 过程,时间上就是创建BeanPostProcessor,保存在容器中
            1)、创建Bean的实例
            2)、populateBean 给Bean的各种属性赋值
            3)、initializeBean 初始化Bean
              1)、invokeAwareMethods() 处理Aware接口方法回调
              2)、applyBeanPostProcessorsBeforeInitialization() 处理后置处理器的postProcessBeforeInitialization方法
              3)、invorkInitMethods() 执行自定义的初始化方法
              4)、applyBeanPostProcessorsAfterInitialization() 执行后置处理器的postProcessAfterInitialization方法
            4)、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--》aspectJAdvisorsBuilder
    ---上面是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程
       4)、finishBeanFactoryInitialization(beanFactory)创建所有剩余的单实例Bean
         1)、调用DefaultListableBeanFactroy的preInstantiateSingletons方法,遍历beanDefinitionNames获取beanName
           依次调用getBean(beanName) 创建对象 getBean->doGetBean()->getSingleton()->
         2)、创建Bean的实例
            (AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个后置处理器,InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation())
            1)、AbstractBeanFactory的doGetBean方法真1正实现向Ioc容器获取Bean的功能,也是触发依赖注入功能的地方。正实现向Ioc容器获取Bean的功能,也是触发依赖注入功能的地方。
              先从getSingleton先后三级缓存中取是否有被创建过的单例Bean,已创建直接使用,否则再创建,放入缓存
            2)、doGetBean,创建单例这里使用了一个匿名内部类调用createBean(),再调用DefaultSingletonBeanRegistry的getSingleton方法,创建Bean实例对象,并且注册给所依赖的对象
            
  
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
  


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值