辽宁建设厅新网站,互动营销是什么意思,咨询行业网站开发,网站建设毕业设计指导老师意见AOP的核心成员是如何被被加载的#xff1f;本篇我们主要分析使用xml的逻辑#xff0c;如果使用注解#xff0c;增加注解处理类即可#xff08;ConfigurationClassPostProcessor#xff09;拿之前分析循环的时候举的例子#x1f330;#xff0c;它的日志切面就是通过xml进…AOP的核心成员是如何被被加载的本篇我们主要分析使用xml的逻辑如果使用注解增加注解处理类即可ConfigurationClassPostProcessor拿之前分析循环的时候举的例子它的日志切面就是通过xml进行配置的配置文件内容如下完整测试代码可参考【实践向】当移除了三级缓存…… 中的示例代码通过ApplicationContext applicationContext new ClassPathXmlApplicationContext(circulate.xml);启动容器进入refresh()方法后先调用prepareRefresh()方法进行的是容器刷新前的准备工作这里的准备工作大致包括5个内容设置容器的启动时间设置活跃状态为true设置关闭状态为false获取Environment对象并加载当前系统的属性值到Environment对象中准备监听器和事件的集合对象默认为空在准备工作完成后开始了下面的创建容器的流程创建容器进入方法obtainFreshBeanFactory()开始Spring容器的创建可以看到此时创建的是上下文对象是ClassPathXmlApplicationContext接着进入方法refreshBeanFactory()中开始BeanFactory的初始化以及XML配置文件的读取和解析读取并解析XML配置文件进入loadBeanDefinitions()终于看到了咱们的doLoadBeanDefinitions() 正式开始读取解析标签️的逻辑registerBeanDefinitions()进入doRegisterBeanDefinition()没错、do-开头的方法都是干实事的开始重头戏(ω)进入parseBeanDefinitions()方法中对于 Element 的处理主要分为两种类型parseDefaultElementparseCustomElement找到对应的handleraop:config就属于自定义元素类型所以我们进入parseCustomElement()方法中进入parseCustomElement()我们可以看到此时的处理器handler为AopNamespaceHandler按照案例代码我们进入了NamespaceHandlerSupport接口中重写了parse进入其一个实现类NamepaceHandlerSupport中由于parser ! null为true再次进入名为parse()的方法中这里主要进行了两个步骤的处理注册自动代理模式创建器解析aop:config下的子节点POINTCUTADVICEASPECT我们依次来看看第一个步骤【注册自动代理模式创建器】configureAutoProxyCreator()进入方法configureAutoProxyCreator()此时集合containingComponents中只有一个元素aop:config进入registerAspectJAutoProxyCreatorIfNecessary()registerOrEscalateApcAsRequired()进入registerOrEscalateApcAsRequired()如果已经存在了自动代理创建器且存在的自动代理创建器与当前不一致那么需要根据优先级来判断下到底需要使用哪个如果已经存在了自动代理创建器且存在的自动代理创建器与当前一致则无需再次创建返回null即可下面的变量表中可以看到这里注册的Bean名为org.springframework.aop.config.internalAutoProxyCreator的beanDefinition并且其中的BeanDefinition的具体Class类为AspectJAwareAdvisorAutoProxyCreator方法registerOrEscalateApcAsRequired()执行到最后的registerBeanDefinition()时当前的BeanDefinition也就是AspectJAwareAdvisorAutoProxyCreator的BeanDefinition就已经注册成功了由下图的静态代码块中也同样添加了InfrastructureAdvisorAutoProxyCreator和AnnotationAwareAspectJAutoProxyCreator这两个类因此可以推断出他俩的注册流程与AspectJAwareAdvisorAutoProxyCreator类似那么问题来了AspectJAwareAdvisorAutoProxyCreator跟我们熟悉的那些BeanPostProcessor、Aware等等有什么关系么(*≧ω≦)我们看下类关系图下图中右下角的就是AspectJAwareAdvisorAutoProxyCreatoruseClassProxyingIfNecessary()方法中主要是对proxy-target-class和expose-proxy这两个属性进行处理如果被代理的目标对象实现了至少一个接口就会使用JDK动态代理该目标类型实现的接口都会被代理如果没有实现任何接口则创建一个Cglib代理对象registerComponentIfNecessary()最后调用方法registerComponentIfNecessary()注册对应的组件接着回到parse()方法中可以看到此时aop:config还是null第二个步骤解析aop:config下的子节点继续解析aop:config子节点下的aop:pointcutaop:adviceaop:aspect在这里会根据获取到的localName进入不同的if条件语句进而执行不同的解析方法parsePointcut()parseAdvisor()parseAspect()下面我们按照我们的测试代码中的XML配置如下图捋一遍流程(ω)由于获取到的localName为aspect满足ASPECT.equals(localName)为true的条件所以进入parseAspect()方法中parseAspect()先获取aop:aspect的两个属性 id属性ref属性代表切面必须配置接着解析aop:aspect下的declare-parents节点通过DeclareParentsAdvisor作为beanClass加载然后继续解析其他节点在获取到节点后遍历循环解析其下的Advice类型的节点通过调用isAdviceNode()判断遍历到的当前节点是否为Advice类型的节点isAdviceNode()判断是否为Advice节点如上图中方法上面的注释Advice类型的节点有5个{code before}{code after}{code after-returning}{code after-throwing}{code around}与上面任何一个类型形同返回值即为true解析成功则继续向下执行parseAdvisor()方法parseAdvisor()先生成了methodDefinition解析advice中的method属性并包装为MethodLocatingFactoryBean对象 、aspectFactoryDef关联aspectName包装为SimpleBeanFactoryAwareAspectInstanceFactory对象这两个RootBeanDefinition对象并依次为他俩赋值随后解析pointcut属性将上面两个对象传入了方法createAdviceDefinition()中包装为AspectJMethodBeforeAdvice对象返回并赋值给名为adviceDef的AbstractBeanDefinition对象最后将这个对象包装为名为advisorDefinition的RootBeanDefinition对象并为相关的属性赋值最后完成注册就可以在parseContext对象的readerContext - reader - registry - beanDefinitionMap属性中看到这个AspectJPointcutAdvisor对象叻AspectJPointcutAdvisor#0那么问题来了这些生成的RootBeanDefinition对象有什么区别吗他们具体都是哪些类呢我们先来详细介绍下createAdviceDefinition()这个方法createAdviceDefinition()进入方法createAdviceDefinition()首先根据adviceElement节点通过调用getAdviceClass()方法分析出是什么类型的Advice获取到一个adviceDefinition对象getAdviceClass()这个方法其实与刚刚介绍过的isAdviceNode()判断的类型是完全一致的继续给刚刚获取到的adviceDefinition对象设置属性值设置aspectName属性和declarationOrder属性设置returning、throwing、arg-name这3个属性先判断有则设置设置构造函数的入参变量MethodAspectJExpressionPointcutAspectInstanceFactory然后解析point-cut节点parsePointcutProperty()至此方法createAdviceDefinition()执行结束返回一个AbstractBeanDefinition类型的对象adviceDef。我们也来回答下介绍方法前的问题这些生成的RootBeanDefinition对象具体都是哪些类呢methodDefinitionMethodLocatingFactoryBeanaspectFactoryDefSimpleBeanFactoryAwareAspectInstanceFactoryadviceDefAspectJMethodBeforeAdviceadviceDefinitionAspectJPointcutAdvisor回到方法parseAspect()中将当前解析过的beanDefinitionadvisorDefinition添加进集合beanDefinitions中接着进入下一轮循环♻️继续解析列表中的节点第二次循环执行完成在parseContext对象的readerContext - reader - registry - beanDefinitionMap属性中又多了一个AspectJPointcutAdvisor对象AspectJPointcutAdvisor#1嘿嘿没错每完成一次循环就会多一个0、1、2……递增这些类外部都是AspectJPointcutAdvisor对象用后缀#1、#2、#3……来区分但是内部真正的通知类型Advisor是不一样的循环结束后返回到parse()方法中由于我在XML配置文件如下图中加了两个aspect标签️所以childElts里有两个Element于是会再按上面得大致流程再执行一遍全部遍历完成后一路返回其实吧说到底BeanDefinition的解析过程( loadBeanDefinitions()也就是配置文件的加载过程毕竟都是Bean嘛^ ^