3 | Spring:AOP实现原理

看给容器中注册了什么组件,这个组件什么时候工作,功能是什么?

@EnableAspectJAutoProxy工作流程

①首先从@EnableAspectJAutoProxy注解入手,它使用@Import注解,加入了一个实现了ImportBeanDefinitionRegistrar的类,叫做AspectJAutoProxyRegistrar

1
2
3
4
5
6
7
8
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}

②也就是说它会往IOC容器中加入相应的bean,到底加入了什么呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@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()方法:

  1. AbstractAutoProxyCreator.setBeanFactory()

    1
    2
    3
    4
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
    this.beanFactory = beanFactory;
    }
  2. AbstractAdvisorAutoProxyCreator.setBeanFactory()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
    super.setBeanFactory(beanFactory);
    ...
    initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
    }

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    this.advisorRetrievalHelper =
    new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
    }
  3. AnnotationAwareAspectJAutoProxyCreator

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @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接口的类开始,逐步往下寻找相关方法实现,如下:

  1. AbstractAutoProxyCreator

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    @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;
    }

    分别打上断点。

工作流程梳理

  1. InstantiationAwareBeanPostProcessor作为一个bean,被加载到beanFactory中。并执行其BeanFactoryAware接口的方法。
  2. 当其他bean初始化时,InstantiationAwareBeanPostProcessor会拦截其他bean的实例化,并创建代理对象返回。也就是执行postProcessBeforeInstantiationpostProcessAfterInitialization

上面的结论是错的,经过后续的debug跟代码,发现最终Divider被Cglib代理是在BeanPostProcessor的afterInitialization中,如下:

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

Cglib执行代理流程

这个像一个有限套娃,也有点像递归,这种包装办法真的很厉害,很服气。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

①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自动配置原理

raft算法演示以及nacos的CP与AP

作者

遇寻

发布于

2020-03-26

更新于

2022-04-21

许可协议

评论