Spring中AOP源码浅析①

本文深入探讨Spring AOP的启用过程,从@EnableAspectJAutoProxy注解出发,讲解AspectJAutoProxyRegistrar如何通过ImportBeanDefinitionRegistrar接口注册Bean,并进一步分析如何通过AopConfigUtils注册Aspect J注解自动代理创建器AnnotationAwareAspectJAutoProxyCreator。文章还介绍了BeanPostProcessor和BeanFactoryAware接口在AOP实现中的角色,以及如何理解AOP的实现原理。
摘要由CSDN通过智能技术生成

上篇文章Spring中AOP的使用讲到@EnableAspectJAutoProxy这个注解开启AOP,这个注解里面又引入了AspectJAutoProxyRegistrar(AspectJ自动代理注册类)这个类。

继续跟进源码,AspectJAutoProxyRegistrar是实现了ImportBeanDefinitionRegistrar这个接口,这个接口在Spring注入Bean的四种方式,看这一篇就够了这篇文章有提到,使用RootBeanDefinition创建Bean的定义,然后通过BeanDefinitionRegistry注册Bean。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
...

这个注册器主要是通过这个接口获取到BeanDefinitionRegistry之后在通过AopConfigUtilsregisterAspectJAnnotationAutoProxyCreatorIfNecessary()方法进行注册Aspect J注释自动代理创建器(AnnotationAwareAspectJAutoProxyCreator)。

AopConfigUtils跟进源码继续看是执行了registerOrEscalateApcAsRequired这个方法,主要还是对AnnotationAwareAspectJAutoProxyCreator类进行定义注册。

...
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
			"org.springframework.aop.config.internalAutoProxyCreator";
...
	@Nullable
	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
			@Nullable Object source) {

		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
	}
...
	@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
			@Nullable Object source) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        //判断是否存在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 = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
        
        //创建Bean定义
		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;
	}

在这一步是定义了名称为org.springframework.aop.config.internalAutoProxyCreator的Bean,该Bean为AnnotationAwareAspectJAutoProxyCreator.class

可以理解为 internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator又是什么?根据继承关系画个大概的类图分析一下

SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 这两个类就很熟了。一个是BeanPostProcesser后置处理器接口,一个是Aware感知接口。

我在聊一聊SpringBean的生命周期——创建、初始化、销毁这篇文章里就有提到这两个接口。

BeanPostProcesser:用于每个Bean创建时的前置后置处理。

Aware:只要Bean实现该接口,则可以获取到相应的组件。这里很明显是为了获取Bean工厂。

那么这样看来就简单多了,只需要看BeanPostProcesser处理器的前置方法(postProcessBeforeInstantiation)和后置方法(postProcessAfterInstantiation)分别做了什么就搞明白了AOP是如何实现的。

 

至于Bean的加载顺序还有优先级,需要再跟进源码,打个断点分析一下。这里需要注意的是Ordered接口是和优先级有关的接口。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值