Spring AOP源码解析(一)Advisor获取

一、入口

AOP的Jar包如下如所示:

META-INF中是Spring自定义标签的配置文件,对<aop>标签的支持

spring.schemas配置如下,作用是定义<aop>标签的内容(根据不同版本,Spring使用不同的xsd文件来描述):

http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd
http\://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframework/aop/config/spring-aop-3.2.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.0.xsd=org/springframework/aop/config/spring-aop-4.0.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.1.xsd=org/springframework/aop/config/spring-aop-4.1.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.2.xsd=org/springframework/aop/config/spring-aop-4.2.xsd
http\://www.springframework.org/schema/aop/spring-aop-4.3.xsd=org/springframework/aop/config/spring-aop-4.3.xsd
http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-4.3.xsd

spring.handles中配置只有一行,如下所示:

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

配置的入口便是AopNamespaceHandler。它的定义如下:

public class AopNamespaceHandler extends NamespaceHandlerSupport {

	/**
	 * 注册几个BeanDefinitionParser,用来支持config、spring-configured、aspectj-autoproxy、scoped-proxy标签的功能
	 */
	@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());
	}

}

二、AspectJAutoProxyBeanDefinitionParser注册AOP组件

在平时使用Spring AOP基于注解配置AOP的时候,配置文件中都需要加入下面这行配置来开启AOP:

	<!--开启字段AOP代理-->
	<aop:aspectj-autoproxy/>

对应到前面的代码中,Spring就会使用AspectJAutoProxyBeanDefinitionParser来解析这行配置:

	public BeanDefinition parse(Element element, ParserContext parserContext) {
		//注册AspectJAnnotationAutoProxyCreator(具体实现类是AnnotationAwareAspectJAutoProxyCreator)
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		//对于注解中子类的处理
		extendBeanDefinition(element, parserContext);
		return null;
	}

代码中重点是registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,该方法会注册AnnotationAwareAspectJAutoProxyCreator:

	public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
		//注册beanName为"org.springframework.aop.config.internalAutoProxyCreator"的bean,如果bean为null的话
		//bean的类型为AspectJAwareAdvisorAutoProxyCreator
		BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
				parserContext.getRegistry(), parserContext.extractSource(sourceElement));
		//对于proxy-target-class以及expose-proxy属性的处理
		useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
		//注册组件并通知,便于监听器进一步处理
		registerComponentIfNecessary(beanDefinition, parserContext);
	}

a、注册AspectJAwareAdvisorAutoProxyCreator

AopConfigUtil.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法实现中,会直接将AspectJAwareAdvisorAutoProxyCreator注册到BeanFactory中:

	public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
		return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
	}

下面是注册(或升级)的源码实现:

	private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		//如果已经存在beanName为"org.springframework.aop.config.internalAutoProxyCreator"的bean并且与当前传入的类型不同,
		//则比较两个bean的优先级,保留优先级高的那个
		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 = findPriorityForClas
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值