看源碼肯定需要一個入口,我們準備了一個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)效果:
* 正常執行:前置通知-->目標方法-->後置通知-->返回通知
* 異常執行:前置通知-->目標方法-->後置通知-->異常通知
*
*
*/