引言

本篇文章详细分析AspectJAotuProxyBeanDefinitionParser,解析下面标签。

1
<aop:aspectj-autoproxy proxy-target-class="false" expose-proxy="false"/>
  • proxy-target-class属性
    强制使用CGLIB动态代理则值为true。spring会自动选择动态代理方案,可以不设置。
  • epose-proxy属性
    暴露当前的代理对象,springAOP只会拦截public方法,不会拦截provided和private方法,
    并且不会拦截public方法内部调用的其他方法,也就是说只会拦截代理对象的方法,即增强的是代理对象,而不是原对象。
    通过设置true,就可以暴露出代理对象,拦截器会获取代理对象,并且将代理对象转换成原对象。从而对内部调用的方法进行增强。

首先看解析器入口方法:

1
2
3
4
5
6
7
8
9
10
11
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
//自带注释的方法名
//如果需要,注册AspectJ注释自动代理创建器
//内部管理的自动代理创建者的bean名称:org.springframework.aop.config.internalAutoProxyCreator
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//对子类处理,扩展BeanDefinition
extendBeanDefinition(element, parserContext);
return null;
}

分为两步:

1、注册AnnotationAwareAspectJAutoProxyCreator

首先看AopNamespaceUtils工具类中的registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);

1
2
3
4
5
6
7
8
9
10
11
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {

// 1.注册或者升级AnnotationAwareAspectJAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
// 2.对于proxy-target-class和expose-proxy属性的处理
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
// 3.注册组件并通知,便于监听器做进一步处理
registerComponentIfNecessary(beanDefinition, parserContext);
}

1.1、注册或者升级AnnotationAwareAspectJAutoProxyCreator

AopConfigUtils工具类中的registerAspectJAnnotationAutoProxyCreatorIfNecessary:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {

//根据需要注册或升级AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
/**
* 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);
}
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";
@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());
}
}
//AnnotationAwareAspectJAutoProxyCreator自动代理创建器,不重新创建
return null;
}
// 不存在自动代理创建器,创建AnnotationAwareAspectJAutoProxyCreator自动代理创建器
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;
}

1.2、对于proxy-target-class和expose-proxy属性的处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, @Nullable Element sourceElement) {
if (sourceElement != null) {
//"proxy-target-class"
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//"expose-proxy"
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}

1.3、注册组件并通知,便于监听器做进一步处理

1
2
3
4
5
6
private static void registerComponentIfNecessary(@Nullable BeanDefinition beanDefinition, ParserContext parserContext) {
if (beanDefinition != null) {
parserContext.registerComponent(
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME));
}
}

2、对子类处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private void extendBeanDefinition(Element element, ParserContext parserContext) {
BeanDefinition beanDef =
parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
if (element.hasChildNodes()) {
addIncludePatterns(element, parserContext, beanDef);
}
}

private void addIncludePatterns(Element element, ParserContext parserContext, BeanDefinition beanDef) {
ManagedList<TypedStringValue> includePatterns = new ManagedList<>();
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (node instanceof Element) {
Element includeElement = (Element) node;
TypedStringValue valueHolder = new TypedStringValue(includeElement.getAttribute("name"));
valueHolder.setSource(parserContext.extractSource(includeElement));
includePatterns.add(valueHolder);
}
}
if (!includePatterns.isEmpty()) {
includePatterns.setSource(parserContext.extractSource(element));
beanDef.getPropertyValues().add("includePatterns", includePatterns);
}
}

tencent.jpg