spring4.3.6源代码 - aop - 命名空间处理器 & Processor & 代理机制

37 篇文章 0 订阅
21 篇文章 0 订阅

通知接收器(advisor)
拦截器(advise)
匹配器(pointcut)

 

《aop命名空间》:
    spring-aop-4.3.6.RELEASE.jar、spring-aspects-4.3.6.RELEASE.jar
    hook机制是:
        aop的“命名空间的指定标签处理器”在处理指定标签的时候,会自动注册bean级别的hook - org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator
    aop的配置 - 使用xml配置
        <aop:scoped-proxy proxy-target-class="true" /> BeanDefinition装饰器机制 - 劫持 BeanDefinition 的信息,以CGLIB生成子类
        <aop:config>
        
    aop的配置 - 使用注解配置
        <aop:include name="aspect4AspectJAutoProxyTag[0-9]" /> 正则表达式,用来匹配通知者接收者的beanName
        当通知接收者的Aspect的value有配置值时,bean的必须scope="prototype"
        @Aspect(...)、@Before(...)、@After(...)、@Around(...)、@AfterReturning(...)、@AfterThrowing(...)

 

org.springframework.aop.config.internalAutoProxyCreator注册的优先级

 注册 XxxAspectJAwareAdvisorAutoProxyCreator的时候有个优先级关系
    APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
    APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
    APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);

<aop:config>



// <aop:config> 居于xml的解析
org.springframework.aop.config.ConfigBeanDefinitionParser.parse
{
	1、如果没有,注册AspectJAwareAdvisorAutoProxyCreator到beanFactory,《beanName为org.springframework.aop.config.internalAutoProxyCreator》
	    如果有设置 proxy-target-class="",那么设置AspectJAwareAdvisorAutoProxyCreator的属性
	        definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
	    如果有设置 expose-proxy="",那么设置AspectJAwareAdvisorAutoProxyCreator的属性
	        definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);


	2、注册子元素
        List<Element> childElts = DomUtils.getChildElements(element);
        for (Element elt: childElts)
        {
            String localName = parserContext.getDelegate().getLocalName(elt);
            if (POINTCUT.equals(localName)) {
                // <aop:pointcut id="aspectJExpressionPointcut01" expression="execution(* cn.java.demo.aoptag.bean.HelloServiceImpl4ConfigAopWithAdvisorTag.method1(..))" />
                // parsePointcut(elt, parserContext); 匹配规则的定义
                1、注册AspectJExpressionPointcut到beanFactory
            }
            else if (ADVISOR.equals(localName)) {
                // <aop:advisor id="aspectJPointcutAdvisor00" pointcut-ref="aspectJExpressionPointcut01" advice-ref="aspectJMethodBeforeAdviceMock"  order="1" />
                // parseAdvisor(elt, parserContext); 定义《匹配规则和切入点处理器的关系》
                2、注册DefaultBeanFactoryPointcutAdvisor到beanFactory
            }
            else if (ASPECT.equals(localName)) {
                // <aop:aspect id="aspectId_12_aspectMethodAround" ref="aspect4AopConfigAllTag12" order="1">  <!-- 以Poxy的方式实现AOP,不会用CGLIB生成子类 -->
                //    <aop:pointcut id="pointcutRefId_12_aspectMethodAround" expression="execution(public String cn.java.demo.aoptag.bean.HelloServiceImpl4ConfigAopWithAdvisorTag1.method3(..))" />
                //    <aop:around method="aspectMethodAround" pointcut-ref="pointcutRefId_12_aspectMethodAround"  />
                // </aop:aspect>
                // parseAspect(elt, parserContext); // 定义《匹配规则和切入点处理器方法的关系》
                1、注册AspectJPointcutAdvisor到beanFactory (存放《表达式beanName和报关接收器的关系》)
                2、注册AspectJExpressionPointcut到beanFactory(表达式bean)
            }
        }
}

// Processor
org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator
{
	1、实例化前
	postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
	{

	}

	2、初始化后
	postProcessAfterInitialization(Object bean, String beanName)
	{
        return wrapIfNecessary(bean, beanName, cacheKey);
        {
            1、过滤不能被代理的
                1、 -- 实现Advice/Pointcut/Advisor/AopInfrastructureBean接口的类不能被代理
                2、 -- 要创建的是“接受通知的对象”,那么就要跳过了,不然陷入死循环
            2、获取符合条件的“通知接受者”列表 --- getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null)
                findEligibleAdvisors(Class<?> beanClass, String beanName)
                {
                    1、扫描所有“通知接受者”列表 - 扫描bean容器,找出实现Advisor接口的bean列表 --- findCandidateAdvisors()
                    2、匹配“通知接受者”列表 --- findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName)
                        1、ClassFilter匹配
                        2、MethodMatcher匹配 - 《类中只要有一个方法能命中,就符合》
                    3、对结果进行排序 --- sortAdvisors(eligibleAdvisors)
                }
           3、创建代理对象 - 返回
                1、配置优化模式
                    new ObjenesisCglibAopProxy(config);

                2、没配置优化模式
                    new JdkDynamicAopProxy(config)
        }
	}
}

<aop:aspectj-autoproxy> 居于注解的解析

// <aop:aspectj-autoproxy> 居于注解的解析
{
    1、如果没有,注册AnnotationAwareAspectJAutoProxyCreator到beanFactory,《beanName为org.springframework.aop.config.internalAutoProxyCreator》
        如果有设置 proxy-target-class="",那么设置AnnotationAwareAspectJAutoProxyCreator的属性
	        definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
	    如果有设置 expose-proxy="",那么设置AnnotationAwareAspectJAutoProxyCreator的属性
	        definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);

	2、设置AnnotationAwareAspectJAutoProxyCreator的属性
	    beanDef.getPropertyValues().add("includePatterns", includePatterns);
}

// Processor
org.springframework.aop.aspectj.autoproxy.AnnotationAwareAspectJAutoProxyCreator
{
	1、实例化前
	postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
	{

	}

	2、初始化后
	postProcessAfterInitialization(Object bean, String beanName)
	{
        return wrapIfNecessary(bean, beanName, cacheKey);
        {
            1、过滤不能被代理的
                1、 -- 实现Advice/Pointcut/Advisor/AopInfrastructureBean接口的类不能被代理
                2、 -- 要创建的是“接受通知的对象”,那么就要跳过了,不然陷入死循环
            2、获取符合条件的“通知接受者”列表 --- getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null)
                findEligibleAdvisors(Class<?> beanClass, String beanName)
                {
                    1、findCandidateAdvisors()
                    {
                        1、扫描所有“通知接受者”列表 - 扫描bean容器,找出实现Advisor接口的bean列表
                        2、居于注解扫描
                            for(迭代所有bean){
                                1、beanName 符合特征 includePatterns
                                2、反射包含@Aspect注解的类里面的所有方法,在方法上查找注解,用InstantiationModelAwarePointcutAdvisorImpl包装方法,获取Advisor列表
                            }
                    }
                    2、匹配“通知接受者”列表 --- findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName)
                        1、ClassFilter匹配
                        2、MethodMatcher匹配 - 《类中只要有一个方法能命中,就符合》
                    3、对结果进行排序 --- sortAdvisors(eligibleAdvisors)
                }
           3、创建代理对象 - 返回
                1、配置优化模式
                    new ObjenesisCglibAopProxy(config);

                2、没配置优化模式
                    new JdkDynamicAopProxy(config)
        }
	}
}

代理机制(切面机制)

调用:
org.springframework.aop.framework.JdkDynamicAopProxy
{
    1、获取符合条件的“通知接受者”列表
        1、ClassFilter匹配
        2、MethodMatcher匹配 - 《调用的方法能命中,就符合》

    2、创建ReflectiveMethodInvocation对象
        1、执行《ReflectiveMethodInvocation对象.proceed()》(FilterChain模式)
            1、调用“通知接受者”,并传入ReflectiveMethodInvocation
                1、执行《业务》代码
                2、执行调用《ReflectiveMethodInvocation对象.proceed()》,触发链条继续执行
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
spring-aop的jar包有多个版本可供选择。其中,版本5.2.0.RELEASE的jar包为spring-aop-5.2.0.RELEASE.jar,版本5.0.10.RELEASE的jar包为spring-aop-5.0.10.RELEASE.jar,版本4.3.6.RELEASE的jar包为spring-aop-4.3.6.RELEASE.jar。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [spring-aop-5.2.0.RELEASE-API文档-中文版.zip](https://download.csdn.net/download/qq_36462452/86089830)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [spring-aop-5.0.10.RELEASE-API文档-中文版.zip](https://download.csdn.net/download/qq_36462452/85209897)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [开发工具 spring-aop-4.3.6.RELEASE](https://download.csdn.net/download/s13596191285/85512891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值