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
| 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
| 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。留到下一节详解。