springboot啓動流程(十一)aop切面處理過程

全部文章

http://www.javashuo.com/article/p-uvudtich-bm.htmlhtml

 

正文

spring的兩大核心就是ioc和aop。在關於ioc依賴注入的文章中,咱們瞭解瞭如何根據BeanDefinition建立Bean,而後在BeanPostProcessor中處理@Autowired和@Resource兩個註解,自動注入Bean。spring

本文將講解另一塊核心內容,aop切面。緩存

 

AOP自動配置

首先,aop切面基於springboot的自動配置。若是不瞭解自動配置,請參考自動配置機制的文章。springboot

爲此,咱們先找到aop自動配置的類AopAutoConfigurationapp

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = false)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
            matchIfMissing = false)
    public static class JdkDynamicAutoProxyConfiguration {

    }

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
            matchIfMissing = true)
    public static class CglibAutoProxyConfiguration {

    }

}

咱們將以Cglib爲主要的瞭解對象,能夠看到CglibAutoProxyConfiguration上註解了一個@EnableAspectJAutoProxy,它意味着開啓切面代理,咱們打開該註解ide

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

    //
}

咱們看到,@Import註解導入了AspectJAutoProxyRegistrar。在自動配置的文章中,咱們瞭解到ConfigurationClassParser將會處理@Import註解。這裏咱們再也不關注如何處理@Import註解,直接打開AspectJAutoProxyRegistrar類看看post

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 註冊自動切面代理的建立器
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        // 省略
    }

}

 

跟進registerAspectJAnnotationAutoProxyCreatorIfNecessaryui

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

繼續跟進registerAspectJAnnotationAutoProxyCreatorIfNecessarythis

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
        BeanDefinitionRegistry registry, @Nullable Object source) {

    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

咱們看到,調用registerOrEscalateApcAsRequired方法指定了一個類AnnotationAwareAspectJAutoProxyCreator,這個類將做爲建立代理的類spa

 

跟進registerOrEscalateApcAsRequired方法

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

    //
    // 構建BeanDefinition
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    // 註冊到Bean容器
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

能夠看到,最終是註冊到了Bean容器中,做爲BeanDefinition存在。咱們能夠認爲aop的自動配置過程就是爲了建立AnnotationAwareAspectJAutoProxyCreator這個類的BeanDefinition。

 

註冊AnnotationAwareAspectJAutoProxyCreator

首先,咱們先看看AnnotationAwareAspectJAutoProxyCreator的繼承結構

能夠看到,AnnotationAwareAspectJAutoProxyCreator最終是實現了BeanPostProcessor,那BeanPostProcessor是何時被建立爲Bean的呢?

這裏,咱們得回到refresh容器過程的refresh方法中,跟進AbstractApplicationContext的refresh方法

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 

        try {
            // 

            // 註冊BeanDefinition到容器
            invokeBeanFactoryPostProcessors(beanFactory);

            // 註冊後置處理器到容器
            registerBeanPostProcessors(beanFactory);

            //
        }
        //
    }
}

在註冊BeanDefinition以後,就會把BeanPostProcessor的BeanDefinition轉化爲了Bean註冊到容器中。registerBeanPostProcessors結束之後,AnnotationAwareAspectJAutoProxyCreator就以Bean的形式存在於BeanFactory中了。

 

觸發AnnotationAwareAspectJAutoProxyCreator

接着,咱們再看AnnotationAwareAspectJAutoProxyCreator被註冊爲Bean之後,是在什麼位置被觸發的。前面,ioc依賴注入的文章中咱們提到過createBean方法,將會根據BeanDefinition建立Bean。

跟進AbstractAutowireCapableBeanFactory的createBean方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    //

    try {
        // BeanPostProcessors 調用
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    //

    try {
        // 建立實例對象
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        //
        return beanInstance;
    }
    //
}

咱們看到,在doCreateBean以前,先觸發resolveBeforInstantiation方法,調用了AnnotationAwareAspectJAutoProxyCreator。

 

切面解析

跟進resolveBeforeInstantiation

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            //
            if (targetType != null) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                //
            }
        }
        //
    }
    return bean;
}

繼續跟進applyBeanPostProcessorBeforeInstantiation方法

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 觸發postProcesBeforeInstantiation
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

繼續跟進AbstractAutoProxyCreator的postProcessBeforeInstantiation方法

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        //
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    //
    return null;
}

isInfrastructureCLass將返回false,跟進AspectJAwareAdvisorAutoProxyCreator的shouldSkip

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    // 返回全部的通知,如@Before @After @AfterThrowing @Round
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    for (Advisor advisor : candidateAdvisors) {
        if (advisor instanceof AspectJPointcutAdvisor &&
                ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
            return true;
        }
    }
    return super.shouldSkip(beanClass, beanName);
}

這裏的findCandidateAdvisors方法,將會從beanFactory中得到註解了@Aspect的類元數據,而後獲取其中定義的Advisor。

到這一步,咱們就已經得到了完成了切面部分的解析工做。

 

代理加強

回到AbstractAutowireCapableBeanFactory的createBean方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    //

    try {
        // BeanPostProcessors 調用
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    //

    try {
        // 建立實例對象
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        //
        return beanInstance;
    }
    //
}

獲取了Advisor,那麼再看看Advisor被加強到Bean上的過程,跟進doCreateBean

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException {
    //

    if (instanceWrapper == null) {
        // 建立實例對象
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    //

    Object exposedObject = bean;
    try {
        // 自動注入
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化Bean,建立代理的入口
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }

    //
    return exposedObject;
}

咱們找到initializeBean,這個初始化Bean的入口,將從這裏開始關注代理加強部分,跟進initializeBean方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

繼續跟進applyBeanPostProcessorsAfterInitialization方法

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

這裏將會調用AbstractAutoProxyCreator的postProcessAfterInitialization方法,跟進方法

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;
}

繼續跟進wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    //

    // 獲取適用於當前Bean的Advisors
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 建立代理
        Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

getAdvicesAndAdvisorsForBean方法將會獲取到能夠加強到該Bean的Advisor,而後createProxy將會建立代理類,並一路返回,若是是單例,則註冊到緩存中

跟進createProxy看看建立代理

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
        @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    //

    // 獲取可用的advisor
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);

    //
    // 建立並返回代理對象
    return proxyFactory.getProxy(getProxyClassLoader());
}

跟進getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}

createAopProxy將會根據條件返回Cglib實現或者jdk動態代理的實現,而後調用它們的getProxy方法去獲取代理對象

 

總結

本文省略了很多細節內容,大致邏輯是從:aop自動配置 -> 解析@Aspect切面對象 -> 代理加強,這麼一個邏輯行文的。

自動配置的核心就是爲了導入一個AnnotationAwareAspectJAutoProxyCreator,該類實現了BeanPostProcessor。因此在建立Bean實例對象以前會觸發解析@Aspect切面對象,獲取Advisor。在生成Bean實例對象以後,會再觸發該類對Bean實例對象作代理加強,加強的Advisor來自以前的解析結果。代理加強的實現有cglib和jdk動態代理兩種。

最後,加強過的代理Bean若是是單例,將跟之前同樣添加到緩存對象中。

相關文章
相關標籤/搜索