Spring源码分析总结(二)-Spring AOP 解析aop:aspectj-autoproxy

  Spring AOP

当前分析的Spring 版本 5.0

  Spring 2.0开始采用@AspectJ注解对POJO标注,使用切点表达式语法进行切点定义.

   Spring支持注解的AOP,需要在配置文件xml中配置<aop:aspectj-autoproxy />

   在Spring中自定义的注解和自定义的标签都会在Spring中找到 注册该注解或者标签的对应解析器。

一、注册解析器-init()追溯

   在配置文件中配置了 <aop:aspectj-autoproxy /> ,在AopNamespaceHandler类中注册了aspectj-autoproxy,

public class AopNamespaceHandler extends NamespaceHandlerSupport {

	/**
	 * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
	 * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
	 * and '{@code scoped-proxy}' tags.
	 */
	@Override
	public void init() {
		// In 2.0 XSD as well as in 2.1 XSD.
		registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
		registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
		registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

		// Only in 2.0 XSD: moved to context namespace as of 2.1
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
	}

}


AopNamespaceHandler类init()方法

 1、这里是 解析自定义元素节点 调用parseCustomElement(Element ele, @Nullable BeanDefinition containingBd)方法



从上图可知,追溯调用了

-->XmlBeanDefinitionReader类的 loadBeanDefinitions(Resource resource) 方法

	@Override
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(new EncodedResource(resource));
	}


由上图可知,一步一步从refresh()方法,一步一步 调用了到XmlBeanDefinitionReader类的 loadBeanDefinitions(Resource resource) 方法 最后开始在AopNamespaceHandler类中注册了aspectj-autoproxy,



2、这里是对子标签下的自定义属性调用decorateBeanDefinitionIfRequired方法进行解析 追溯到开始也调用了 loadBeanDefinitions方法 也就是开始解析xml文件的时候开始




二、注册解析器

        所有的解析器,都实现了BeanDefinitionParser接口,入口都是从BeanDefinitionParser接口的方法parse()开始

        AspectJAutoProxyBeanDefinitionParser类的parse方法如下:

@Override
	@Nullable
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);//注册AnnotationAwareAspectJAutoProxyCreator
		extendBeanDefinition(element, parserContext);//对于注解中子类的处理
		return null;
	}

   AspectJAutoProxyBeanDefinitionParser类的parse方法追溯如下,也是从loadBeanDefinitions()

    -->loadBeanDefinitions(EncodedResource)

    -->doLoadBeanDefinitions()

    -->registerBeanDefinitions()

   -->一步一步 最后到--》parse()方法


    

   parse方法里面的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法实现如下:

	public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
                //注册或升级AutoProxyCreator定义beanName为org.Springframework.aop.config.internalAutoProxyCreator的BeanDefinition
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); //对于proxy-target-class以及expose-proxy属性的处理
		registerComponentIfNecessary(beanDefinition, parserContext);//注册组件并通知,便于监听器做进一步处理,其中beanDefinition的className是AnnotationAwareAspectJAutoProxyCreator
	}

1、-->AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary

-->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()); //这里拿到已经创建的创建器,然后设置beanClassName
				}
			}
			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;
	}

2、--> AopNamespaceUtils类的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法的

          -》useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);

           useClassProxyingIfNecessary实现了 proxy-target-class属性和expose-proxy属性的处理

	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.forceAutoProxyCreat
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值