Spring AOP源码学习:AOP 注解的解析

我们知道,当解析到 <aop:aspectj-autoproxy /> 注解时,会调用 AspectJAutoProxyBeanDefinitionParser 的 parse方法。

关于自定义注解的解析内容之前 IoC 的文章介绍过了,如果不了解的可以参考:Spring IoC:parseCustomElement 详解

AspectJAutoProxyBeanDefinitionParser#parse

==========================================

@Override

public BeanDefinition parse(Element element, ParserContext parserContext) {

// 1.注册AspectJAnnotationAutoProxyCreator

AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);

// 2.对于注解中子节点的处理

extendBeanDefinition(element, parserContext);

return null;

}

1.注册 AspectJAnnotationAutoProxyCreator,见代码块1。

代码块1:AopNamespaceUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary


public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(

ParserContext parserContext, Element sourceElement) {

// 1.注册AspectJAnnotationAutoProxyCreator

BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(

parserContext.getRegistry(), parserContext.extractSource(sourceElement));

// 2.对于proxy-target-class以及expose-proxy属性的处理

useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);

// 3.注册组件并通知,便于监听器做进一步处理

registerComponentIfNecessary(beanDefinition, parserContext);

}

1.注册 AspectJAnnotationAutoProxyCreator,见代码块2。

2.对于 proxy-target-class 以及 expose-proxy 属性的处理,见代码块3。

代码块2:AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary


public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {

return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);

}

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {

Assert.notNull(registry, “BeanDefinitionRegistry must not be null”);

// 1.如果注册表中已经存在beanName=org.springframework.aop.config.internalAutoProxyCreator的bean,则按优先级进行选择。

// beanName=org.springframework.aop.config.internalAutoProxyCreator,可能存在的beanClass有三种,按优先级排序如下:

// InfrastructureAdvisorAutoProxyCreator、AspectJAwareAdvisorAutoProxyCreator、AnnotationAwareAspectJAutoProxyCreator

if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {

// 拿到已经存在的bean定义

BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);

// 如果已经存在的bean的className与当前要注册的bean的className不相同,则按优先级进行选择

if (!cls.getName().equals(apcDefinition.getBeanClassName())) {

// 拿到已经存在的bean的优先级

int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());

// 拿到当前要注册的bean的优先级

int requiredPriority = findPriorityForClass(cls);

if (currentPriority < requiredPriority) {

// 如果当前要注册的bean的优先级大于已经存在的bean的优先级,则将bean的className替换为当前要注册的bean的className,

apcDefinition.setBeanClassName(cls.getName());

}

// 如果小于,则不做处理

}

// 如果已经存在的bean的className与当前要注册的bean的className相同,则无需进行任何处理

return null;

}

// 2.如果注册表中还不存在,则新建一个Bean定义,并添加到注册表中

RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);

beanDefinition.setSource(source);

// 设置了order为最高优先级

beanDefinition.getPropertyValues().add(“order”, Ordered.HIGHEST_PRECEDENCE);

beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

// 注册BeanDefinition,beanName为org.springframework.aop.config.internalAutoProxyCreator

registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);

return beanDefinition;

}

org.springframework.aop.config.internalAutoProxyCreator 是内部管理的自动代理创建者的 bean 名称,可能对应的 beanClassName 有三种,对应的注解如下:

InfrastructureAdvisorAutoProxyCreator:<tx:annotation-driven />

AspectJAwareAdvisorAutoProxyCreator:<aop:config />

AnnotationAwareAspectJAutoProxyCreator:<aop:aspectj-autoproxy />

当同时存在多个注解时,会使用优先级最高的 beanClassName 来作为 org.springframework.aop.config.internalAutoProxyCreator 的 beanClassName。本系列文章暂不考虑同时存在其他注解的情况,所以在这边会注册的 beanClassName 为:AnnotationAwareAspectJAutoProxyCreator。

代码块3:useClassProxyingIfNecessary


private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {

if (sourceElement != null) {

boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));

if (proxyTargetClass) {

// 如果节点设置了proxy-target-class=true,则给beanName为org.springframework.aop.config.internalAutoProxyCreator

// 的BeanDefinition添加proxyTargetClass=true的属性,之后创建代理的时候将强制使用Cglib代理

AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值