3 | Spring:AOP实现原理
看给容器中注册了什么组件,这个组件什么时候工作,功能是什么?@EnableAspectJAutoProxy工作流程①首先从@EnableAspectJAutoProxy注解入手,它使用@Import注解,加入了一个实现了ImportBeanDefinitionRegistrar的类,叫做Aspect
看给容器中注册了什么组件,这个组件什么时候工作,功能是什么?
@EnableAspectJAutoProxy工作流程
①首先从@EnableAspectJAutoProxy注解入手,它使用@Import注解,加入了一个实现了ImportBeanDefinitionRegistrar的类,叫做AspectJAutoProxyRegistrar
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
②也就是说它会往IOC容器中加入相应的bean,到底加入了什么呢?
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
从registerBeanDefinitions()方法开始,可以一直跟到AopConfigUtils.registerOrEscalateApcAsRequired(),在这个函数里面,它往IOC容器中注册了一个AnnotationAwareAspectJAutoProxyCreator,名称为AUTO_PROXY_CREATOR_BEAN_NAME,即org.springframework.aop.config.internalAutoProxyCreator。
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@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;
}
// 创建AnnotationAwareAspectJAutoProxyCreator的bean,
// 名称为AUTO_PROXY_CREATOR_BEAN_NAME
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
了解AnnotationAwareAspectJAutoProxyCreator的功能,就等于知道了AOP的原理。首先看看它的继承关系图。

它的父类中,实现了两个接口,这两个接口参见bean的生命周期,所以搞清楚这两个接口在何时工作、工作内容即可搞明白AOP的整理流程。
①有一个BeanFactoryAware接口;
②还有一个SmartInstantiationAwareBeanPostProcessor接口,它继承自InstantiationAwareBeanPostProcessor,它继承自BeanPostProcessor,但是与BeanPostProcessor不一样。InstantiationAwareBeanPostProcessor作用于实例化阶段的前后,BeanPostProcessor作用于初始化阶段的前后。

工作时机
BeanFactoryAware
按照上面类图中,从最先实现BeanFactoryAware接口的类,依次往下找相关的实现,即setBeanFactory()方法:
AbstractAutoProxyCreator.setBeanFactory()
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
AbstractAdvisorAutoProxyCreator.setBeanFactory()
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
...
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper =
new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
AnnotationAwareAspectJAutoProxyCreator
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
分别打上断点。
SmartInstantiationAwareBeanPostProcessor
按照上面的类图,从最先实现SmartInstantiationAwareBeanPostProcessor接口的类开始,逐步往下寻找相关方法实现,如下:
AbstractAutoProxyCreator
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
分别打上断点。
工作流程梳理
InstantiationAwareBeanPostProcessor作为一个bean,被加载到beanFactory中。并执行其BeanFactoryAware接口的方法。- 当其他bean初始化时,
InstantiationAwareBeanPostProcessor会拦截其他bean的实例化,并创建代理对象返回。也就是执行postProcessBeforeInstantiation和postProcessAfterInitialization。
上面的结论是错的,经过后续的debug跟代码,发现最终Divider被Cglib代理是在BeanPostProcessor的afterInitialization中,如下:

其中的创建代理对象的逻辑如下:

Cglib执行代理流程
这个像一个有限套娃,也有点像递归,这种包装办法真的很厉害,很服气。
①AfterThrowing
try {
return mi.proceed();②
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
②AfterReturning
Object retVal = mi.proceed();③
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
③After
try {
return mi.proceed();④
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
④Before
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();⑤
⑤invokeJoinpoint();
Netty源码学习系列④接收消息
Spring Cloud Alibaba Sentinel简易搭建与配置
Spring Boot Admin构建及用途
xxljob分布式定时任务
ELK日志系统搭建 elasticsearch、logstash、kibana
kafka集群搭建
redis集群搭建
Spring Boot自动配置原理