目录
  1. xml解析
spring AOP(2) 注解方式xml配置解析

xml解析

spring IoC初始化时注解解析一样,AOP配置部分的解析同样是在BeanDefinitionParserDelegate类的parseCustomElement方法中进行的,aop对应命名空间http://www.springframework.org/schema/aop

里面对应的解析器如下:

元素名 解析器
aspectj-autoproxy AspectJAutoProxyBeanDefinitionParser
spring-config SpringConfiguredBeanDefinitionParser
config ConfigBeanDefinitionParser

这一次我们主要阅读的是AOP注解方式的源码,注解方式的配置文件如下

1
<aop:aspectj-autoproxy />

由此可知AOP注解方式的解析器是AspectJAutoProxyBeanDefinitionParser。进入到解析方法中,

1
2
3
4
5
public BeanDefinition parse(Element element, ParserContext parserContext) {
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}

我们先来看看第一个方法registerAspectJAnnotationAutoProxyCreatorIfNecessary,

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

BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
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
// 下面这段代码其实就是做了这么一件事,注册AnnotationAwareAspectJAutoProxyCreator这个类
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
"org.springframework.aop.config.internalAutoProxyCreator";

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, 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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// 这部分是用来设置proxy-target-class和expose-proxy属性的,其中proxy-target-class属性是用来设置是否强制使用cglib代理的
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}

还有一个registerComponentIfNecessary方法根据名称是用来注册组件的,但具体的并未详细阅读。

现在再回到最外面的那层方法中,我们来看看extendBeanDefinition方法,

1
2
3
4
5
6
7
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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void addIncludePatterns(Element element, ParserContext parserContext, BeanDefinition beanDef) {
ManagedList<TypedStringValue> includePatterns = new ManagedList<TypedStringValue>();
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);
}
}

这一块是用来解析如下的aop:include标签的

1
2
3
4
<aop:aspectj-autoproxy>
<aop:include name="hello" />
<aop:include name="world" />
</aop:aspectj-autoproxy>

到这里xml配置文件的解析部分就结束了。

那么aop的入口其实就是前面提到的一个类AnnotationAwareAspectJAutoProxyCreator。留到下一节详解。

文章作者: 谷河
文章链接: https://www.lyytaw.com/spring/spring_aop_xml_parse/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 谷河|BLOG