1. 程式人生 > >SpringAOP源碼讀書筆記

SpringAOP源碼讀書筆記

處理器 assert asr 遍歷 test apc should sta one

1、首先配置類裏面需要加入註解EnableAspectJAutoProxy,後面的(proxyTargetClass = true)涉及到動態代理的類型後面會解釋

Configuration和ComponentScan以及Component註解這邊就不贅述了;

package com.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.ImportResource; import org.springframework.stereotype.Component; @Configuration @Component("app") @ComponentScan("com.aop") @EnableAspectJAutoProxy//(proxyTargetClass = true) public class AopConfig { }


2、我們進入到EnableAspectJAutoProxy裏面可以看出這個類裏面通過@Import的形式註入了一個類:AspectJAutoProxyRegistrar;

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {


3、進入到這個類發現他實現了我們大名鼎鼎的ImportBeanDefinitionRegistrar接口,熟悉Spring代碼的同學都知道;Spring初始化期間,會調用實現了ImportBeanDefinitionRegistrar的類裏面的registerBeanDefinitions方法,所以我們看這個方法:registerAspectJAnnotationAutoProxyCreatorIfNecessary

package
org.springframework.context.annotation; import org.springframework.aop.config.AopConfigUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata;
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) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } } }


4、一直跟蹤這個函數我們會發現最終會執行到這個函數裏面:registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);會把AnnotationAwareAspectJAutoProxyCreator註冊到beanDefinitionMap裏面,名稱是:org.springframework.aop.config.internalAutoProxyCreator

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

        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

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

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

public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
            "org.springframework.aop.config.internalAutoProxyCreator";

5、到這裏我們需要來看Spring實例化的過程了:首先會有一個測試類;annotationConfigApplicationContext.register(AopConfig.class);及其之前的代碼就不再解釋了,這邊就是創建了一個bean工廠(DefaultListableBeanFactory類型的),然後會向工廠裏面註冊我們的配置類以及6個類;

package com.aop;

import com.config.AppConfig;
import com.luban.dao.UserDao;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestAop {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
        annotationConfigApplicationContext.register(AopConfig.class);
        annotationConfigApplicationContext.refresh();
        AopDao dao = (AopDao) annotationConfigApplicationContext.getBean("aopdao");
        dao.test();

    }
}

技術分享圖片

6、我們來看annotationConfigApplicationContext.refresh();裏面執行的代碼邏輯(此處中間的邏輯只簡單的說明一下,主要看我們的AOP是如何實現的)

refresh方法裏面會執行invokeBeanFactoryPostProcessors(beanFactory);之前的方法都是做了一些初始化,這二個方法裏面完成了Bean的掃描並放到了beanDefinitionMap裏面;這個方法會在處理完Import的類以後結束;有關於Spring中間的實例化過程會在後面的文章中分享;讓我們看AOP的過程;

invokeBeanFactoryPostProcessors(beanFactory);

7、在對象創建完成以後會執行一個方法:這個方法傳入的參數是bean的name和實例化以後的對象以及BeanDefinition;在這個方法裏面會執行後置處理器的before和after方法,這邊會遍歷我們環境中的所有的後置處理器;其中有一個後置處理器是我們上面第4步的時候註冊進去的;看下面截圖:

exposedObject = initializeBean(beanName, exposedObject, mbd);
@Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {

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

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

技術分享圖片

當遍歷到這個後置處理器的時候,在postProcessAfterInitialization方法裏面,會通過wrapIfNecessary方法返回一個對象,進入到這個方法可以看出裏面調用了

@Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

進入到這個方法可以看出裏面調用了

Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

來看一下createProxy方法:方法裏面前面的isProxyTargetClass()就是判斷配置類裏面的下面的這個註解後面是為true還是false

@EnableAspectJAutoProxy//(proxyTargetClass = true)

看這個方法裏面最後面一句:

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

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        return proxyFactory.getProxy(getProxyClassLoader());
    }
public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        return getAopProxyFactory().createAopProxy(this);
    }

下面這邊厲害了,請看代碼:這邊就解釋了為社麽SpringAOP動態代理有的時候用的是JDK,有的時候用的是CGLIB

@Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            //如果對象所屬的類是接口
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                //采用的是JDK動態代理
                return new JdkDynamicAopProxy(config);
            }
            //采用的是CGLIB代理
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            //采用的是JDK動態代理
            return new JdkDynamicAopProxy(config);
        }
    }

SpringAOP源碼讀書筆記