Skip to content

Latest commit

 

History

History
155 lines (121 loc) · 5.96 KB

Spring-Aop如何生效.md

File metadata and controls

155 lines (121 loc) · 5.96 KB

Spring AOP 如何生效

解析

  • 在使用 Spring AOP 技术的时候会有下面这段代码在 xml 配置文件中出现,来达到 Spring 支持 AOP
 <aop:aspectj-autoproxy/>
  • 源码阅读目标找到了,那么怎么去找入口或者对这句话的标签解析方法呢?项目中使用搜索

    image-20200115083744268

    这样就找到了具体解析方法了

org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser

  • 类图

image-20200115084031725

@Override@NullablepublicBeanDefinitionparse(Elementelement, ParserContextparserContext) { // 注册 <aop:aspectj-autoproxy/>AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); // 子类解析extendBeanDefinition(element, parserContext); returnnull; }
/** * 注册 <aop:aspectj-autoproxy/> * @param parserContext * @param sourceElement */publicstaticvoidregisterAspectJAnnotationAutoProxyCreatorIfNecessary( ParserContextparserContext, ElementsourceElement) { // 注册或者升级beanBeanDefinitionbeanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); // proxy-target-class 和 expose-proxy 标签处理useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); // 注册组件并且交给监听器registerComponentIfNecessary(beanDefinition, parserContext); }
  • org.springframework.aop.config.AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
@NullablepublicstaticBeanDefinitionregisterAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistryregistry, @NullableObjectsource) { // 注册或者升级 AspectJreturnregisterOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
  • org.springframework.aop.config.AopConfigUtils.registerOrEscalateApcAsRequired
/** * 注册或者升级 bean * @param cls 类 * @param registry 注册器 * @param source 源类 * @return */@NullableprivatestaticBeanDefinitionregisterOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistryregistry, @NullableObjectsource) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); // 判断注册器是否包含org.springframework.aop.config.internalAutoProxyCreatorif (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { // 获取注册器BeanDefinitionapcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); // 创建新的bean对象if (!cls.getName().equals(apcDefinition.getBeanClassName())) { intcurrentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); intrequiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } // 即将创建的Bean对象和当前的注册器相同返回nullreturnnull; } RootBeanDefinitionbeanDefinition = newRootBeanDefinition(cls); beanDefinition.setSource(source); // 设置加载顺序beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 注册bean定义registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); returnbeanDefinition; }

org.springframework.aop.config.AopNamespaceUtils.useClassProxyingIfNecessary

/** * proxy-target-class 和 expose-proxy 标签处理 */privatestaticvoiduseClassProxyingIfNecessary(BeanDefinitionRegistryregistry, @NullableElementsourceElement) { if (sourceElement != null) { // 处理 proxy-target-classbooleanproxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE)); if (proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } // 处理 expose-proxybooleanexposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE)); if (exposeProxy) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } }
  • org.springframework.aop.config.AopConfigUtils.forceAutoProxyCreatorToUseClassProxying
publicstaticvoidforceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistryregistry) { if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinitiondefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE); } }
  • forceAutoProxyCreatorToExposeProxy方法就不贴出代码了,操作和forceAutoProxyCreatorToUseClassProxying一样都是将读取到的数据放入 bean 对象作为一个属性存储

总结

  • 实现org.springframework.beans.factory.xml.BeanDefinitionParser接口的类,多用于对 xml 标签的解析,并且入口为parse方法,如果是一个 bean 对象通常会和 Spring 监听器一起出现
close