Spring源碼分析~AOP如何生成代理對象

看源碼肯定需要一個入口,我們準備了一個demo,很簡單,一個main方法,一個config類,一個對象(需要被代理的對象),一個日誌切面類;

一個對象:

package com.anotation.aop;

import org.springframework.stereotype.Service;

@Service
public class MathCalculator {
	
	public int divide(int i,int j){
		System.out.println("MathCalculator...div...");
		return i/j;	
	}
}

切面類:用於給上面的對象增強日誌功能

package com.anotation.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;

import java.util.Arrays;

/**
 * 切面類 @Aspect
 */
@Aspect
@Service
public class LogAspects {

	@Pointcut("execution(public int com.anotation.aop.MathCalculator.*(..))")
	public void pointCut(){};

	@Before("pointCut()")
	public void logStart(JoinPoint joinPoint){
		Object[] args = joinPoint.getArgs();
		System.out.println(""+joinPoint.getSignature().getName()+"方法運行,@Before:{"+Arrays.asList(args)+"}");
	}
	
	@After("com.anotation.aop.LogAspects.pointCut()")
	public void logEnd(JoinPoint joinPoint){
		System.out.println(""+joinPoint.getSignature().getName()+"方法運行,@After");
	}
	
	@AfterReturning(value="pointCut()",returning="result")
	public void logReturn(JoinPoint joinPoint,Object result){
		System.out.println(""+joinPoint.getSignature().getName()+"@AfterReturning:"+"{"+result+"}");
	}

	//JoinPoint一定要出現在參數的第一位
	@AfterThrowing(value="pointCut()",throwing="exception")
	public void logException(JoinPoint joinPoint,Exception exception){
		System.out.println(""+joinPoint.getSignature().getName()+"方法運行產生異常,@AfterThrowing:"+"{"+exception+"}");
	}

}

config類:

package com.anotation.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@EnableAspectJAutoProxy
@Configuration
@ComponentScan(value = "com.anotation.aop")
public class MainConfigOfAOP {

}

重點看@EnableAspectJAutoProxy的作用,它是一個註解,主要作用是引入:@Import(AspectJAutoProxyRegistrar.class)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
	boolean proxyTargetClass() default false;
	boolean exposeProxy() default false;
}

而AspectJAutoProxyRegistrar.java的作用主要是註冊:AnnotationAwareAspectJAutoProxyCreator.java,這個類是一個後置處理器BeanPostProcessor,這個AnnotationAwareAspectJAutoProxyCreator是實現aop功能的核心,因爲他會在它的方法postProcessAfterInitialization()中對目標對象進行增強(實現AOP),後面會細說。

main函數:

package com.atguigu.test;

import com.anotation.aop.MathCalculator;
import com.anotation.config.MainConfigOfAOP;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class IOCTest_AOP {
	@Test
	public void test01() throws InterruptedException {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
		MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
		mathCalculator.divide(4, 2);
		Thread.sleep(2000);
		applicationContext.close();
	}
}

先看運行結果:

divide方法運行,@Before:{[4, 2]}
MathCalculator...div...
divide方法運行,@After
divide@AfterReturning:{2}

可以看到,增強已經生效,下面現在開始分析源碼;分析MathCalculator是何時被增強的(生成代理對象),因爲MathCalculator沒有實現接口,那它應該無法用jdk動態代理來實現,而必須用CGLIB來實現?源碼會解釋一切。

先看第一行:new AnnotationConfigApplicationContext(MainConfigOfAOP.class),這是一個構建方法,代碼如下:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	this();
	register(annotatedClasses);
	refresh();
}

重度看refresh()方法裏面的操作;

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        try {
            // Instantiate all remaining (non-lazy-init) singletons.
            finishBeanFactoryInitialization(beanFactory);
        }
    }
}

我們要看的MathCalculator是如何被增強處理的,看主要代碼finishBeanFactoryInitialization(beanFactory)中,進入方法:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // Register a default embedded value resolver if no bean post-processor
    // (such as a PropertyPlaceholderConfigurer bean) registered any before:
    // at this point, primarily for resolution in annotation attribute values.
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }

    // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // Stop using the temporary ClassLoader for type matching.
    beanFactory.setTempClassLoader(null);

    // Allow for caching all bean definition metadata, not expecting further changes.
    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons();
}

我們要看的在最後一行:beanFactory.preInstantiateSingletons(),該beanFactory是DefaultListableBeanFactory,繼續進入preInstantiateSingletons方法:

@Override
public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isDebugEnabled()) {
        this.logger.debug("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                    isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                        @Override
                        public Boolean run() {
                            return ((SmartFactoryBean<?>) factory).isEagerInit();
                        }
                    }, getAccessControlContext());
                }
                else {
                    isEagerInit = (factory instanceof SmartFactoryBean &&
                            ((SmartFactoryBean<?>) factory).isEagerInit());
                }
                if (isEagerInit) {
                    getBean(beanName);
                }
            }
            else {
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

我們要的在這個方法裏面的getBean(beanName);一直根據會到:AbstractBeanFactory.getBean(String beanName)這個方法裏面:這個方法調用類內部的AbstractBeanFactory.doGetBean方法:

protected <T> T doGetBean(
        final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
        throws BeansException {

    final String beanName = transformedBeanName(name);
    Object bean;

    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isDebugEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                        "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else {
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            }
            else {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }
        }

        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        try {
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    registerDependentBean(dep, beanName);
                    try {
                        getBean(dep);
                    }
                    catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // Create bean instance.
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    @Override
                    public Object getObject() throws BeansException {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            destroySingleton(beanName);
                            throw ex;
                        }
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }

            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                }
                finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }

            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
                catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                            "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                            ex);
                }
            }
        }
        catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        }
        catch (TypeMismatchException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Failed to convert bean '" + name + "' to required type '" +
                        ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

這個代碼很長,我們只看我們要的核心:下面這一段代碼:

// Create bean instance.
if (mbd.isSingleton()) {
    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
        @Override
        public Object getObject() throws BeansException {
            try {
                return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
                // Explicitly remove instance from singleton cache: It might have been put there
                // eagerly by the creation process, to allow for circular reference resolution.
                // Also remove any beans that received a temporary reference to the bean.
                destroySingleton(beanName);
                throw ex;
            }
        }
    });
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

看裏面的return createBean(beanName, mbd, args),調用的是:AbstractAutowireCapableBeanFactory.createBean這個方法:

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;

    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    }
    catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                "BeanPostProcessor before instantiation of bean failed", ex);
    }

    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    if (logger.isDebugEnabled()) {
        logger.debug("Finished creating instance of bean '" + beanName + "'");
    }
    return beanInstance;
}

我們要的在Object beanInstance = doCreateBean(beanName, mbdToUse, args)這一行裏面:doCreateBean很長,我們重點看如下幾行:

// Initialize the bean instance.
Object exposedObject = bean;
    try {
    populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
}

重點看exposedObject = initializeBean(beanName, exposedObject, mbd)這行代碼,跟進去:

AbstractAutowireCapableBeanFactory.initializeBean():

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
                invokeAwareMethods(beanName, bean);
                return null;
            }
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

重點看這一行:wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName),進入這個方法:

AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization():

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

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

我們已經能看到後置處理器的遍歷了,在getBeanPostProcessors()會有一個後置處理器叫做:AnnotationAwareAspectJAutoProxyCreator,執行其postProcessAfterInitialization方法,實際是執行其父類的AbstractAutoProxyCreator.postProcessAfterInitialization()方法:父類postProcessAfterInitialization如下:

@Override
public Object postProcessAfterInitialization(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;
}

return wrapIfNecessary(bean, beanName, cacheKey)這行,AbstractAutoProxyCreator.wrapIfNecessary();

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // Create proxy if we have advice.
    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;
}

這個方法裏面的return的bean已經是我們要的代理對象了(aop增強的對象了);現在好辦了,看如何生成的:看這行:

Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
createProxy方法實現如下:
protected Object createProxy(
        Class<?> beanClass, String beanName, 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());
}

先看這幾行:

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

用於判斷被代理類是否實現了接口,即能否用jdk動態代理進行增強;再看下面幾行:

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
    proxyFactory.setPreFiltered(true);
}

這幾行是獲取需要哪些增強,即advice;

最後一行

proxyFactory.getProxy(getProxyClassLoader());

根據上面的判斷決定使用CGLIB還是JDK動態代理來創建代理對象;默認的兩個實現:

CglibAopProxy.java和JdkDynamicAopProxy.java

 

大體流程已經論述完了,可能你有很多疑惑,這個需要不斷的debug去調試才能搞得明白,Spring源碼讀起來還是有點難度的,我目前其實也是一知半解,讀者見諒~我這裏只講了關於如何生成代理對象的邏輯,而關於BeanPostProcessor相關的加載都沒有詳細說明,待我自己搞清楚了再詳細寫~

來個總結:

/**
 * 說明:
 *   1、環繞通知,動態代理,手動推進目標方法的運行(joinPoint.procced())
 *   2、@EnableAspectJAutoProxy,開啓基於註解的aop模式
 *
 *
 *   AOP原理:看給容器中註冊了什麼組件,這個組件什麼時候工作,這個組件的功能
 *      @EnableAspectJAutoProxy註解:
 *    1、@EnableAspectJAutoProxy
 *    @Import(AspectJAutoProxyRegistrar.class):給容器中導入AspectJAutoProxyRegistrar:
 *       AspectJAutoProxyRegistrar他給容器註冊一個AnnotationAwareAspectJAutoProxyCreator
 *
 *    AnnotationAwareAspectJAutoProxyCreator
 * 		AnnotationAwareAspectJAutoProxyCreator
 * 			->AspectJAwareAdvisorAutoProxyCreator
 * 				->AbstractAdvisorAutoProxyCreator
 * 					->AbstractAutoProxyCreator
 * 							implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
 * 						關注後置處理器(在bean初始化完成前後做的事情)、自動裝配BeanFactoryAware
 *
 *
 * 	  AbstractAutoProxyCreator.setBeanFactory()
 *
 *    AbstractAutoProxyCreator.有後置處理器的邏輯
 *
 *    AbstractAdvisorAutoProxyCreator.setBeanFactory()->initBeanFactory()
 *
 *    AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
 *
 * 流程
 *    1、傳入配置類,創建ioc容器
 *    2、註冊配置類,調用refresh()方法,刷新容器
 *    3、registerBeanPostProcessors(beanFactory);註冊bean的後置處理器來方便攔截bean的創建
 *       1) 先獲取ioc容器已經定義了的需要創建對象的所有BeanPostProcessor
 *       2) 給容器中加別的BeanPostProcessor
 *       3)優先註冊實現了PriorityOrdered接口的BeanPostProcessor
 *       4)再給容器中註冊實現了Ordered接口的BeanPostProcessor
 *       5)沒有實現優先級接口的BeanPostProcessor
 *       6) 註冊BeanPostProcessor,實際上就是創建BeanPostProcessor對象,保存在容器中
 * 				創建internalAutoProxyCreator的BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)
 * 				1、創建Bean的實例
 * 				2、populateBean:給bean的各種屬性賦值
 * 				3、initializeBean:初始化bean
 * 						1、invokeAwareMethods() :
 * 						2、applyBeanPostProcessorsBeforeInitialization() 執行後置處理器postProcessBeforeInitialization
 * 						3、invokeInitMethods():執行自定義的初始化方法
 * 						4、applyBeanPostProcessorsAfterInitialization()  執行後置處理器postProcessAfterInitialization
 * 				4、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)創建成功
 *       7) 把BeanPostProcessor註冊到BeanFactory中:
 *          beanFactory.addBeanPostProcessor(beanPostProcessor)
 *  ========以上是創建和註冊AnnotationAwareAspectJAutoProxyCreator的過程 ========
 *
 *    4、完成BeanFactory剩餘的初始化工作:創建剩下的單實例bean
 *       1) 遍歷獲取容器所有的bean,依次創建對象
 *       2)、創建bean
 *
 *  AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用
 *  1、每一個bean創建之前,調用postProcessBeforeInstantiation();
 *     關心MathCalculator和LogAspect的創建
 *     1) 判斷當前bean是否在advisedBean中(保存了所有需要增強的bean)
 *     2)  判斷當前bean是否是基礎類型的Advice、Pointcut、Aspect。。。
 *
 *  2、創建對象 調用postProcessAfterInitialization:
 *      1)、獲取bean的所有增強器
 *         1)獲取候選當所有增強器(找到哪些通知方法是需要切入當前bean方法的)
 *         2)獲取到能在bean使用的增強器
 *         3)給增強器排序
 *      2)、保存當前bean在advisedBeans中
 *      3)、創建bean的代理對象,創建當前bean的代理對象
 *         1)獲取所有增強器(通知方法)
 *         2)保存到proxyFactory中
 *         3)創建代理對象
 *              JdkDynamicAopProxy(config);jdk動態代理
 * 				ObjenesisCglibAopProxy(config);cglib動態代理
 * 	    4)、給容器返回當前組件使用cglib增強了的代理對象
 * 	    5)、以後容器中獲取到的就是這個組件的代理對象,執行目標方法的時候,代理對象就會執行通知方法
 * 	3、目標方法執行
 * 	    容器中保存了組件的代理對象(cglib增強後的對象),這個對象裏面保存了詳細信息
 * 	    1)CglibAopProxy.intercept()攔截目標方法的執行
 * 	    2)根據ProxyFactory對象獲取將要執行的目標方法的攔截器鏈
 * 	    3)沒有攔截器鏈,直接執行目標方法
 * 	       攔截器鏈(每一個通知方法又被包裝爲方法攔截器,利用MethodInterceptor機制)
 * 	    4)如果有攔截器鏈,把需要執行的目標對象,目標方法,攔截器鏈等信息傳入創建一個CglibMethodInvocation對象
 * 	       並調用Object retval = mi.proceed()
 * 	    5)攔截器鏈的觸發過程
 * 	       1)如果沒有攔截器執行目標方法,或者攔截器的索引和攔截器數組-1大小一樣,執行目標方法
 * 	       2)鏈式獲取每一個攔截器,攔截器執行invoke方法,每一個攔截器等待下一個攔截器執行完成返回以後再來執行
 * 	          攔截器鏈的機制,保證通知方法與目標方法的執行順序
 *
 * 	 總結:
 * 	   1)@EnableAspectJAutoProxy註解開啓AOP功能
 * 	   2)@EnableAspectJAutoProxy會給容器註冊一個組件AnnotationAwareAspectJAutoProxyCreator
 *     3)AnnotationAwareAspectJAutoProxyCreator是一個後置處理器
 *     4)容器的創建流程:
 *        1)registerBeanPostProcessors()註冊後置處理器:創建AnnotationAwareAspectJAutoProxyCreator
 *        2)finishBeanFactoryInitialization()初始化剩下的單實例bean
 *           1)創建業務邏輯組件和切面組件
 *           2)AnnotationAwareAspectJAutoProxyCreator攔截組件的創建過程
 *           3)組件創建完成之後,判斷組件是否需要增強
 *              是:切面的通知方法包裝成增強器(Advisor);給業務邏輯組件創建一個代理對象
 *     5)執行目標方便
 *        1)代理對象執行目標方法
 *        2)CglibAopProxy.intercept()攔截目標方法的執行
 *          1)得到目標方法的攔截器鏈(增強器包裝成攔截器MethodInterceptor)
 *          2) 利用攔截器的鏈式機制,依次進入每一個攔截器進行執行
 *          3)效果:
 *              正常執行:前置通知-->目標方法-->後置通知-->返回通知
 *              異常執行:前置通知-->目標方法-->後置通知-->異常通知
 *
 *
 */

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章