spring 几种AbstractAdvisorAutoProxyCreator如何选择呢,这里举例AspectJAwareAdvisorAutoProxyCreator和AnnotationAwareAspectJAutoProxyCreator。
spring的AOP配置工具类AopConfigUtils
里面会初始化三个AbstractAdvisorAutoProxyCreator子类。
/**
* The bean name of the internally managed auto-proxy creator.
*/
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
/**
* Stores the auto proxy creator classes in escalation order.
*/
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
static {
// Set up the escalation list...
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}再来看看AopNamespaceHandler类
public void init() {
// In 2.0 XSD as well as in 2.5+ XSDs
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace in 2.5+
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}默认执行的解析类是ConfigBeanDefinitionParser
看看配置类
.......
<aop:config>
<aop:aspect ref="logUtil">
<aop:pointcut id="myPoint" expression="..."/>
<aop:around method="around" pointcut-ref="myPoint"></aop:around>
</aop:aspect>
</aop:config>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
.......如果我配置了标签<aop:aspectj-autoproxy></aop:aspectj-autoproxy>,为什么就能使用AspectJAutoProxyBeanDefinitionParser解析呢?
这个疑问其实是因为我看到配置<aop:aspectj-autoproxy></aop:aspectj-autoproxy>后,其实ConfigBeanDefinitionParser也是会执行的(解析aop:confi标签),执行完后发现beanDefinitionMap里面的key:org.springframework.aop.config.internalAutoProxyCreator的value用的是AspectJAwareAdvisorAutoProxyCreator!!!
等执解析<aop:aspectj-autoproxy>后beanDefinitionMap里面的key:org.springframework.aop.config.internalAutoProxyCreator的value用的是AnnotationAwareAspectJAutoProxyCreator!!!
一开始我以为,是覆盖了,其实确实是覆盖,不过这个覆盖也挺有意思!!!
于是我把配置文件改为
.......
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<aop:config>
<aop:aspect ref="logUtil">
<aop:pointcut id="myPoint" expression="..."/>
<aop:around method="around" pointcut-ref="myPoint"></aop:around>
</aop:aspect>
</aop:config>
.......按照预期,beanDefinitionMap里面的key:org.springframework.aop.config.internalAutoProxyCreator的value用的是AspectJAwareAdvisorAutoProxyCreator吧,实际发现依然是AnnotationAwareAspectJAutoProxyCreator,怎么回事,难道有优先级!!深入debug发现,确实是的。
我们来看下AopConfigUtils的这段代码
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
private static int findPriorityForClass(@Nullable String className) {
for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) {
Class<?> clazz = APC_PRIORITY_LIST.get(i);
if (clazz.getName().equals(className)) {
return i;
}
}
throw new IllegalArgumentException(
"Class name [" + className + "] is not a known auto-proxy creator class");
}
发现什么了?原来真的有优先级,优先级通过APC_PRIORITY_LIST的下标来决定,下标越大,优先级越高。
感觉这种做法好巧妙,就随手记录下,这个做法以后做项目遇到也可以借鉴,spring不愧是一个优秀的框架。
第一次文章,个人能力有限,可能细节不太对的地方请指教。
文章探讨了Spring框架中AOP配置的几个关键类,如AbstractAdvisorAutoProxyCreator的子类AspectJAwareAdvisorAutoProxyCreator和AnnotationAwareAspectJAutoProxyCreator。通过AopConfigUtils和AopNamespaceHandler的源码分析,揭示了自动代理创建器的优先级机制,特别是如何通过APC_PRIORITY_LIST列表来决定哪个子类具有更高的优先级。作者指出,这个设计在处理不同类型的AOP配置时很有巧妙之处,并建议在项目中可以借鉴这种做法。
1082

被折叠的 条评论
为什么被折叠?



