首页 > 编程学习 > 【Spring - AOP】--- AOP核心后置处理器的创建过程

文章目录

  • 1 简诉
  • 2 internalAutoProxyCreator的注册
  • 3 internalAutoProxyCreator的继承关系
  • 4 internalAutoProxyCreator创建+初始化过程
    • 4.1 入口refresh()方法
    • 4.2 跟进processor创建+初始化的源码
    • 4.3 internalAutoProxyCreator初始化过程中BeanFactoryAware的作用时机


1 简诉

spring-aop的核心原理用一句概况,我觉得可以是:

在目标业务bean创建+初始化过程中spring利用动态代理机制对原始的业务bean进行了增强。

通过前面几篇文章的铺垫,其实应该比较容易想到,具体的执行者肯定就是后置处理器(BeanPostProcessor),这里对应的后置处理器在spring中的

  • bean name为org.springframework.aop.config.internalAutoProxyCreator
  • 具体的实体类对象为AnnotationAwareAspectJAutoProxyCreator。

当然internalAutoProxyCreator既然是对目标对象进行增强的处理器,那它肯定在目标对象创建之前就已经存在于spring的IOC容器了,本篇文章将主要来探索一下该对象是如何被率先注入到IOC容器的。


2 internalAutoProxyCreator的注册

在《【Spring - AOP】— AOP使用简介》这篇文章里讲到,要想开启Spring的AOP功能,必须在配置类中加上@EnableAspectJAutoProxy注解,下面为该注解的源码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class) //比较重要的一个注解
public @interface EnableAspectJAutoProxy {
	//true强制使用CGLIB代理,false非强制
	boolean proxyTargetClass() default false;
	//是否暴露被代理的类
	boolean exposeProxy() default false;
}

通过EnableAspectJAutoProxy源码,可以看到一个比较重要的注解@Import(AspectJAutoProxyRegistrar.class),其实在《【Spring注解】@Import》那篇文章里就已经介绍过@Import注解是框架源码中经常用到的一个向IOC容器中注入bean的注解 — internalAutoProxyCreator的注册正是通过该注解完成的。跟进AspectJAutoProxyRegistrar源码:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//真正注册internalAutoProxyCreator的代码
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		//省略N行
	}

可以看到它是用了实现ImportBeanDefinitionRegistrar接口的方式进行bean的注册 — 在《【Spring注解】@Import》也讲到过。接着跟进代码,可以看到如下两个比较重要的方法

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
		BeanDefinitionRegistry registry, @Nullable Object source) {
	//第一个参数为AnnotationAwareAspectJAutoProxyCreator的类型
	return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

//实际进行internalAutoProxyCreator注册的方法
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
		Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	//先去看注册中心registry里是否已经有internalAutoProxyCreator的定义了
	//注意:AUTO_PROXY_CREATOR_BEAN_NAME其实就是org.springframework.aop.config.internalAutoProxyCreator
	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;
	}
	//利用AnnotationAwareAspectJAutoProxyCreator的class类型新建RootBeanDefinition
	RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
	//向beanDefinition对象中加入其它一些属性
	beanDefinition.setSource(source);
	beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
	beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	//将新定义的beanDefinition注入到注册中心
	//注意:AUTO_PROXY_CREATOR_BEAN_NAME其实就是org.springframework.aop.config.internalAutoProxyCreator
	registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
	return beanDefinition;
}

对比《【Spring注解】@Import》那篇文章可知,上面方法中最终要的就是利用给定的类型AnnotationAwareAspectJAutoProxyCreator.class新建一个RootBeanDefinition 对象,并将该对象注入到注册中心,这样spring就会在启动时将该对象注入到IOC容器中。


3 internalAutoProxyCreator的继承关系

在了解了internalAutoProxyCreator的注册机制之后,接下来看一下internalAutoProxyCreator的继承关系,其继承关系图如下。接下来我会在internalAutoProxyCreator的创建+初始化过程中对图中标注的三点进行稍微比较细致的讲解。
在这里插入图片描述


4 internalAutoProxyCreator创建+初始化过程

4.1 入口refresh()方法

无论是BeanPostProcessor还是业务bean的创建入口都是AbstractApplicationContext类中的refresh()方法,下面仅展示了processor注册(或者也可以叫做定义)、processor创建+初始化和业务bean创建+初始化的代码:

//调用processor的注册方法 -> 本文第2部分将internalAutoProxyCreator注册到注册中心就是这里进行调用的
// Invoke factory processors registered as beans in the context.  
invokeBeanFactoryPostProcessors(beanFactory); // 对应源代码528行
//processor的创建+初始化
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); //对应源代码531行

//省略N行代码

//其他普通单实例bean的创建+初始化 -> 如我们的业务bean
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//对应源码546行

4.2 跟进processor创建+初始化的源码

跟进去registerBeanPostProcessors,可以看到会进一步进入到public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext)方法,该方法的关键逻辑如下:
在这里插入图片描述


4.3 internalAutoProxyCreator初始化过程中BeanFactoryAware的作用时机

之前的文章如《【bean的生命周期】— 对象创建+初始化流程分析 — 【重点@Autowired的作用时机】》在讲单实例bean的初始化过程即下面方法的具体实现时,只讲到了前置处理、bean的初始化和后置处理器如下图。

exposedObject = initializeBean(beanName, exposedObject, mbd);

在这里插入图片描述
但实际上initializeBean方法的具体实现类里在前置处理器之前还有一个方法:

invokeAwareMethods(beanName, bean);

跟进该方法的源码:

private void invokeAwareMethods(final String beanName, final Object bean) {
	if (bean instanceof Aware) {
		//如实现了BeanNameAware将bean在IOC容器中的beanname给当前bean
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		//如实现了BeanClassLoaderAware将ClassLoader给当前bean
		if (bean instanceof BeanClassLoaderAware) {
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
		//如实现了BeanFactoryAware将BeanFactory给当前bean
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

可以看到,其实很简单,就是判断当前bean是否实现了上面三个Aware,如果实现了,就将相应的内容给到当前bean。看到这里肯定就会明白为什么我会在《真实工作中经常用到的Aware使用简介》那篇文章的代码注释里写 BeanNameAware接口的调用逻辑会在前置处理器applyBeanPostProcessorsBeforeInitialization方法之前了。

Copyright © 2010-2022 ngui.cc 版权所有 |关于我们| 联系方式| 豫B2-20100000