Spring Aop源码学习

参考博客:https://blog.csdn.net/songxinjianqwe/article/details/78826293
10.1
横切关注点:
散布于应用多处的功能(影响引用多处的功能)
面向切面编程(aspect oriented programming):
关注点在于怎么把横向关注点与业务逻辑相分离,实现横切关注点和他们所影响的对象之间的解耦
应用场景:
日志、声明式事物、安全和缓存
AOP术语
1、切面(aspect)
类是对物体特征的抽象,切面就是对横切关注点的抽象
2、连接点(joinpoint)
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器
3、切入点(pointcut)
对连接点进行拦截的定义
4、通知(advice)
所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、返回、环绕通知五类
5、目标对象
代理的目标对象
6、织入(weave)
将切面应用到目标对象并导致代理对象创建的过程
7、引介(introduction)
在不修改代码的前提下,引介可以在运行期为类动态地添加一些方法或字段
AOP概述
AOP 代理可以分为两个部分:解析AOP标签和创建AOP代理。这两个部分都与IOC容器有关。如想了解AOP源码请先了解IOC源码。
1.解析AOP标签发生在IOC的解析标签的过程,即解析自定义标签 <aop:aspectj-autoproxy />,解析结果是在BeanFactory中注册了一个名为AnnotationAwareAspectJAutoProxyCreator的bean,用于创建AOP代理。
2.创建AOP代理发生在IOC的createtBean中,在doCreateBean之前会先调用resolveBeforeInstantiation方法,在该方法中会调用实现了BeanPostProcessor接口的后处理的postProcessAfterInstantiation方法。
而在解析AOP标签中注册的AnnotationAwareAspectJAutoProxyCreator便实现了BeanPostProcessor接口。AnnotationAwareAspectJAutoProxyCreator会在postProcessAfterInstantiation方法中根据定义的advisor,使用JDK动态代理或CGLIB动态代理来增强bean。

解析AOP标签:

Ioc的parseDefaultElement/parseCustomElement                                             ----解析默认/自定义标签中的自定义解析
    NamespaceHandler.parse()                                                            ----
    NamespaceHandlerSupport.parse()
    AspectJAutoProxyBeanDefinitionParser.parse()
    AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary()            ----注册这个creator
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary()           ----注册或升级AutoProxyCreator定义beanName为internalAutoProxyCreator的BeanDefinition
        useClassProxyingIfNecessary()                                                   ----处理proxy-target-class以及expose-proxy属性
        registerComponentIfNecessary()                                                  ----注册组件并通知,便于监听器做进一步处理

创建AOP代理:

Ioc的doCreateBean()之前会先调用resolveBeforeInstantiation()
    AbstractAutoProxyCreator.postProcessAfterInitialization()
    wrapIfNecessary()   
        getAdvicesAndAdvisorsForBean() 获取所有适合应用到该bean的所有advisor
        上面方法触发的findEligibleAdvisors()  Eligible合格的
            findCandidateAdvisors() 获取所有增强
                AbstractAutoProxyCreator.findCandidateAdvisors()  获取配置文件中的增强
                    BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()  拿到增强的执行代码
                        BeanFactoryUtils.beanNamesForTypeIncludingAncestors() 从BeanFactory中获取所有对应Advisor的类
                BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdcisors()  获取标记@AspectJ注解的类中增强     
1)遍历所有beanName,所有在beanFactory中注册的bean都会被提取出来 
2)遍历所有beanName,找出声明@Aspect注解的类,进行进一步的处理 
3)对标记为AspectJ注解的类进行增强的提取  4)将提取结果加入缓存 
                    ReflectiveAspectJAdvisorFactory.getAdvisors()增强器的获取
                        getAdvisor()   对普通advisor的获取
                            getPointcut()  获取切点信息
                                AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod() 寻找特定的注解类获取方法上的注解
                                    findAnnotation() 获取指定方法上的注解并使用AspectJAnnotation封装
                        SyntheticInstantiationAdvisor()  同步实例化advisor保证增强使用前的实例化
                        getDeclareParentsAdvisor()    获取DeclareParents注解
            findAdvisorsThatCanApply()获取匹配的增强并应用
                 canApply()真正的匹配(处理引入增强、处理PointcutAdvisor、无切入点的始终匹配)            
        createProxy()  创建代理(1.获取Advisor,2.根据获取的advisor进行代理)                   
            buildAdvisors() 封装拦截器转化为Advisor(AdvisorAdapterRegistry.wrap())     
                DefaultAdvisorAdapterRegistry.wrap()  根据要封装的对象类型转化为advisor
            getProxy()   
                createAopProxy()   创建代理
                    DefaultAopProxyFactory.createAopProxy()     调用相应的代理方法 
                getProxy()   根据情况选择获取哪种代理     
            JdkDynamicAopProxy.getProxy()   
                ReflectiveMethodInvocation.proceed()   执行拦截器链的方法
                    invokeJoinpoint()   执行切点方法      
                        invoke()   执行拦截器方法
            CglibAopProxy.getProxy()   
                getCallbacks()   
       设置拦截器,将拦截器封装在DynamicAdvisedInterceptor中,再次调用代理的时候会调用DynamicAdvisedIntercepter的intercept()
                createProxyClassAndInstance()   生成代理类以及创建代理                 

CGLIB对于方法的拦截是通过将自定义的拦截器(实现了MethodInterceptor接口)加入Callback中并在调用代理时直接激活拦截器的intercept方法实现的,那么在getCallback中实现了这样一个目的:DynamicAdvisedInterceptor继承自MethodInterceptor,加入到Callback中后,在再次调用代理时会直接调用DynamicAdvisedInterceptor中的intercept方法。
CGLIB方式实现的代理,其核心逻辑在DynamicAdvisedInterceptor中的intercept方法中(JDK动态代理的核心逻辑是在invoke方法中)。

个人总结
aop是基于ioc的,包含两部分aop标签解析+创建aop代理,需要搞清楚advisor、interceptor、method、pointcut。
1.解析AOP标签在IOC的解析自定义标签 <aop:aspectj-autoproxy />,解析结果是在BeanFactory中注册了一个名为AnnotationAwareAspectJAutoProxyCreator的bean,用于创建AOP代理。
2.创建AOP代理发生在IOC的createtBean中,在doCreateBean之前会先调用resolveBeforeInstantiation方法,在该方法中会调用实现了BeanPostProcessor接口的后处理的postProcessAfterInstantiation方法。
而在解析AOP标签中注册的AnnotationAwareAspectJAutoProxyCreator便实现了BeanPostProcessor接口。AnnotationAwareAspectJAutoProxyCreator会在postProcessAfterInstantiation方法中根据定义的advisor,使用JDK动态代理或CGLIB动态代理来增强bean。
创建AOP的脑图:http://naotu.baidu.com/file/d02f3eaca44025efd07efa91f8841749?token=95a0c6e476f4a6cd

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值