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

本文详细解析了Spring AOP的源码,从入口开始,介绍如何注册AOP组件,包括AspectJAutoProxyBeanDefinitionParser的作用,以及如何处理proxy-target-class和expose-proxy属性。接着,文章探讨了如何创建AOP代理,涉及Bean的创建、是否需要代理的判断,以及获取和应用Advisor的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、入口

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值