好玩Spring之@EnableAspectJAutoProxy解读

前言

在Spring中,如果不在配置类中添加@EnableAspectJAutoProxy,那么所有切面注解是不生效的(springboot因为有自动配置,所以不需要开发人员手工配置@EnableAspectJAutoProxy)

例子

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class AppConfig {
}
@Aspect
@Component
public class LogAspects {
	@Pointcut("within(tzb.aop..*)")
	public void pointCut() {
	}

	@Before("pointCut()")
	public void logStart(JoinPoint joinPoint){
		Object[] args = joinPoint.getArgs();
		System.out.println(joinPoint.getSignature().getName()+" 运行。。。@Before "+ Arrays.asList(args));
	}
}

源码解读

下面,我们就来看下@EnableAspectJAutoProxy这个注解,究竟做了什么

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	boolean proxyTargetClass() default false;

	boolean exposeProxy() default false;

}

看import里的代码

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

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

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			// 如果proxyTargetClass为true,则强制指定AutoProxyCreator使用CGLIB进行代理
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			// exposeProxy属性
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}

一路深入追踪AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);这个代码,来到org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired方法

private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
		// 省略。。。

		// 注册InfrastructureAdvisorAutoProxyCreator(它继承了BeanPostProcessor)
		// 将class注册到容器中,order的执行顺序调整为最优  
    // 在aop中,这里会注册AnnotationAwareAspectJAutoProxyCreator.class这个类到容器
		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;
	}

这个代码里,主要是把AnnotationAwareAspectJAutoProxyCreator.class这个类注册到容器。

AnnotationAwareAspectJAutoProxyCreator

那AnnotationAwareAspectJAutoProxyCreator.class这个类又是干嘛用的呢?
它的继承关系,如下图
在这里插入图片描述
BeanPostProcessor:后置处理器,即在bean初始化完成前后做些事情
BeanFactoryAware:自动注入BeanFactory

故事,还是要从我们所熟悉的refresh()方法开始说起,上下文的获取,必然会调用此方法

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 省略代码...
			
			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);
			// 省略代码...
		}
	}

在refresh()方法中,我们重点来看以下2个方法。

invokeBeanFactoryPostProcessors(beanFactory)

// Invoke factory processors registered as beans in the context.
// 把factory processors先注册进context
invokeBeanFactoryPostProcessors(beanFactory);

这个方法里,会调用到如下方法

private static void invokeBeanDefinitionRegistryPostProcessors(
			Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

		for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanDefinitionRegistry(registry);
		}
	}

经过org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions()方法

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	// 省略代码
	this.reader.loadBeanDefinitions(configClasses);
	// ...
}

在这里插入图片描述

当beanName为appConfig时,会走到如下代码
在这里插入图片描述
接着到这里,以下这个代码,就是我们在文章开头看到的代码了。

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

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			// 如果proxyTargetClass为true,则强制指定AutoProxyCreator使用CGLIB进行代理
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			// exposeProxy特性
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

继续跟踪
在这里插入图片描述

这里,

  1. 会把AnnotationAwareAspectJAutoProxyCreator这个类注册为BeanDefinition,beanName为org.springframework.aop.config.internalAutoProxyCreator
  2. 添加了order属性
    这里也是我们在文章开头见到的代码,原来AnnotationAwareAspectJAutoProxyCreator就是这样注册到容器的。

至此
我们回到refresh(),来看下效果,如下图
果然org.springframework.aop.config.internalAutoProxyCreator已经放到了beanFactory中。
在这里插入图片描述
invokeBeanFactoryPostProcessors(beanFactory)方法这样就执行完了。
internalAutoProxyCreator加入容器了,但是它还并没有被实例化和初始化。

我们接着往下看。

registerBeanPostProcessors(beanFactory)

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

在这里插入图片描述

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
	// 省略代码...
	// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
    // 省略代码...
}

在上面的代码中,我们知道internalAutoProxyCreator是加入Order属性的,所以在registerBeanPostProcessors(beanFactory)方法中,会走到如上代码。
如上代码,会调用beanFactory.getBean(ppName, BeanPostProcessor.class);
一路追踪,进入doCreateBean()方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
	// 省略代码...
	// 执行bean初始化
	exposedObject = initializeBean(beanName, exposedObject, mbd);
	// 省略代码...
}

经过initializeBean()方法。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		// 生命周期 step7 BeanNameAware 、BeanClassLoaderAware 、BeanFactoryAware
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
		// 省略代码。。。
}
private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory

@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		super.setBeanFactory(beanFactory);
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
			throw new IllegalArgumentException(
					"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
		}
		initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
	}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		super.initBeanFactory(beanFactory);
		if (this.aspectJAdvisorFactory == null) {
			this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
		}
		this.aspectJAdvisorsBuilder =
				new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
	}

这里创建了ReflectiveAspectJAdvisorFactory 和 BeanFactoryAspectJAdvisorsBuilderAdapter 2个类。
至此,AnnotationAwareAspectJAutoProxyCreator的注册就已经完成了,虽然期间代码很长很多,但是只要理清脉络,还是还是很清楚的。

至此,以下beanFactory.getBean(ppName, BeanPostProcessor.class);这段代码算是执行完了。

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
	// 省略代码...
	// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
    // 省略代码...
}

registerBeanPostProcessors(beanFactory);方法也就执行完了(这个方法里剩余的部分没什么可看的)。

  • 11
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值