Bean的創(chuàng)建過程
spring注解版單實(shí)例Bean的創(chuàng)建是容器啟動(dòng)的時(shí)候調(diào)用getBean(beanName)創(chuàng)建,然后保存到IOC容器中;多實(shí)例Bean每次都會(huì)getBean(beanName)創(chuàng)建新的實(shí)例
調(diào)用的方法是
org.springframework.context.support.AbstractApplicationContext#refresh
?org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
??org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons
???org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
????org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
getBean(java.lang.String)方法調(diào)用了doGetBean(name, null, null, false)處理Bean的創(chuàng)建
我們來看看doGetBean()做了哪些處理,這里主要分析單實(shí)例Bean的創(chuàng)建過程。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// 1.先獲取緩存中保存的單實(shí)例Bean。如果能獲取到說明這個(gè)Bean之前被創(chuàng)建過(所有創(chuàng)建過的單實(shí)例Bean都會(huì)被緩存起來),如果bean的定義信息scope是多例,就不會(huì)被緩存
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
......
// 如果緩存中有,判斷這個(gè)Bean是否是FactoryBean,如果不是FactoryBean,直接返回sharedInstance
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 2.如果緩存中不存在對(duì)應(yīng)Bean的實(shí)例
else {
// 判斷這個(gè)bean是否正在創(chuàng)建中
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
......忽略部份代碼
if (!typeCheckOnly) {
// 3.標(biāo)記當(dāng)前bean已經(jīng)被創(chuàng)建(或即將創(chuàng)建)
markBeanAsCreated(beanName);
}
try {
//4.獲取Bean的定義信息
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 5.獲取當(dāng)前Bean所依賴的其他Bean
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 {
// 6.如果當(dāng)前Bean依賴了其他Bean,通過getBean()先把所依賴的Bean先創(chuàng)建出來
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 7.如果是單實(shí)例Bean
if (mbd.isSingleton()) {
// 創(chuàng)建Bean實(shí)例對(duì)象并添加到IOC容器中
sharedInstance = getSingleton(beanName, () -> {
try {
//8.單實(shí)例Bean的創(chuàng)建
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 判斷當(dāng)前Bean是不是FactoryBean,不是就直接返回sharedInstance(原來的Bean實(shí)例)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
......忽略部份代碼
}
上**面代碼 8.單實(shí)例Bean的創(chuàng)建,getSingleton方法內(nèi)調(diào)用了createBean(beanName, mbd, args)是創(chuàng)建Bean的流程 分析createBean(beanName, mbd, args) **
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
......忽略部份代碼
try {
//讓BeanPostProcessors(后置處理器)有機(jī)會(huì)返回代理而不是目標(biāo)bean實(shí)例
// 判斷容器中是否有InstantiationAwareBeanPostProcessor的實(shí)現(xiàn)(比如開啟AOP時(shí)就會(huì)調(diào)用),如果有則執(zhí)行InstantiationAwareBeanPostProcessor
// InstantiationAwareBeanPostProcessors會(huì)先觸發(fā):postProcessBeforeInstantiation();
//如果有返回值(一般不會(huì)有返回值):再觸發(fā)postProcessAfterInitialization()
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);
}
try {
// 如果前面的InstantiationAwareBeanPostProcessor沒有返回代理對(duì)象,調(diào)用doCreateBean創(chuàng)建
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
......
}
最終調(diào)用doCreateBean(beanName, mbdToUse, args)方法創(chuàng)建完成Bean的創(chuàng)建
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//BeanWrapper 存儲(chǔ)對(duì)象的實(shí)例
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 1.創(chuàng)建Bean實(shí)例(利用工廠方法或者對(duì)象的構(gòu)造器創(chuàng)建出Bean實(shí)例)
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
......
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 2.調(diào)用MergedBeanDefinitionPostProcessor(后置處理器)的postProcessMergedBeanDefinition方法
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
......
// Initialize the bean instance. 初始化bean實(shí)例
Object exposedObject = bean;
try {
// 3.給bean的屬性賦值
// 1)賦值之前會(huì)從容器中獲取InstantiationAwareBeanPostProcessor(后置處理器)執(zhí)行 postProcessProperties()
// 2)再執(zhí)行postProcessPropertyValues() (應(yīng)用Bean屬性的值,即可以對(duì)屬性值進(jìn)行修改(這個(gè)時(shí)候?qū)傩灾颠€未被設(shè)置(還未調(diào)用set賦值),但是我們可以修改原本該設(shè)置進(jìn)去的屬性值))
// 3)最后屬性利用setter方法等進(jìn)行賦值 applyPropertyValues(beanName, mbd, bw, pvs)
populateBean(beanName, mbd, instanceWrapper);
// 4.Bean初始化
//1) invokeAwareMethods(beanName, bean);執(zhí)行xxxAware接口的方法
// 2)applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 執(zhí)行后置處理器初始化的前置方法(bean初始化之前調(diào)用) BeanPostProcessor.postProcessBeforeInitialization()
// 3)執(zhí)行初始化方法
//1)如果該Bean實(shí)現(xiàn)了InitializingBean接口;執(zhí)行接口規(guī)定的初始化
// 2)如果指定了自定義初始化方法( @Bean(initMethod = "init")),執(zhí)行自定義初始化方法
//4.applyBeanPostProcessorsAfterInitialization執(zhí)行后置處理器初始化的后置方法(bean初始化之后調(diào)用)BeanPostProcessor.postProcessAfterInitialization()
exposedObject = initializeBean(beanName, exposedObject, mbd)
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
......
// Register bean as disposable.
try {
// 注冊(cè)Bean的銷毀方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
createBean創(chuàng)建完成之后返回Bean實(shí)例對(duì)象然后繼續(xù)走getSingleton方法將Bean實(shí)例緩存到容器的singletonObjects的Map中(調(diào)用addSingleton())
if (mbd.isSingleton()) {
// createBean創(chuàng)建Bean實(shí)例對(duì)象,getSingleton將其緩存到singletonObjects的Map中
sharedInstance = getSingleton(beanName, () -> {
try {
//8.單實(shí)例Bean的創(chuàng)建
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 判斷當(dāng)前Bean是不是FactoryBean,不是就直接返回sharedInstance(原來的Bean實(shí)例)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
總結(jié)單實(shí)例Bean的創(chuàng)建過程
getBean(beanName) 創(chuàng)建對(duì)象
?1.doGetBean(name, null, null, false)
??1)先獲取緩存中保存的單實(shí)例Bean。如果能獲取到說明這個(gè)Bean之前被創(chuàng)建過,直接返回回(所有創(chuàng)建過的單實(shí)例Bean都會(huì)被緩存起來,如果bean的定義信息scope是多例,就不會(huì)被緩存)
??2)緩存中獲取不到,開始Bean的創(chuàng)建對(duì)象流程
??3)標(biāo)記當(dāng)前bean已經(jīng)被創(chuàng)建(或即將創(chuàng)建)
??4)獲取Bean的定義信息(依賴、屬性、作用域等Bean的信息都存在BeanDefinition)
??5)從定義信息中g(shù)etDependsOn獲取當(dāng)前Bean所依賴的其他Bean,如果有調(diào)用getBean()把依賴的Bean先創(chuàng)建出來(注意,這個(gè)依賴是指@DependsOn指定的其他bean,當(dāng)前bean的屬性依賴)
??6)createBean(beanName, mbd, args) 創(chuàng)建當(dāng)前Bean的實(shí)例對(duì)象
????1、調(diào)用Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 讓BeanPostProcessors(后置處理器)有機(jī)會(huì)返回代理而不是目標(biāo)bean實(shí)例,判斷容器中是否有InstantiationAwareBeanPostProcessor的實(shí)現(xiàn)(比如開啟AOP時(shí)就會(huì)調(diào)用),如果有InstantiationAwareBeanPostProcessors會(huì)先觸發(fā):postProcessBeforeInstantiation();如果有返回值(一般不會(huì)有返回值):再觸發(fā)postProcessAfterInitialization()
????2、如果前面的InstantiationAwareBeanPostProcessor沒有返回代理對(duì)象,調(diào)用doCreateBean創(chuàng)建
????3、Object beanInstance = doCreateBean(beanName, mbdToUse, args) 創(chuàng)建Bean實(shí)例對(duì)象
??????1.instanceWrapper = createBeanInstance(beanName, mbd, args); 創(chuàng)建Bean實(shí)例(利用工廠方法或者對(duì)象的構(gòu)造器創(chuàng)建出Bean實(shí)例)
??????2.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);從容器中獲取MergedBeanDefinitionPostProcessor(后置處理器)并調(diào)用postProcessMergedBeanDefinition方法
??????3.populateBean(beanName, mbd, instanceWrapper); 給Bean屬性賦值
????????1/賦值之前會(huì)從容器中獲取InstantiationAwareBeanPostProcessor(后置處理器)
????????2/執(zhí)行InstantiationAwareBeanPostProcessor的postProcessProperties()進(jìn)行處理
????????3/再執(zhí)行postProcessPropertyValues() (應(yīng)用Bean屬性的值,即可以對(duì)屬性值進(jìn)行修改(這個(gè)時(shí)候?qū)傩灾颠€未被設(shè)置(還未調(diào)用set賦值),但是我們可以修改原本該設(shè)置進(jìn)去的屬性值))
????????4/最后屬性利用setter方法進(jìn)行賦值 applyPropertyValues(beanName, mbd, bw, pvs)
??????4.initializeBean(beanName, exposedObject, mbd); 對(duì)Bean進(jìn)行初始化處理
????????1/invokeAwareMethods(beanName, bean);判斷當(dāng)前Bean是否實(shí)現(xiàn)了xxxAware的接口,如果是就執(zhí)行xxxAware接口的方法(比如ApplicationContextAware:setApplicationContext())
????????2/applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 后置處理器的前置處理BeanPostProcessor.postProcessBeforeInitialization() (bean初始化之前調(diào)用)
????????3/執(zhí)行初始化方法,首先判斷:如果該Bean實(shí)現(xiàn)了InitializingBean接口,執(zhí)行接口規(guī)定的初始化 。然后判斷:如果指定了自定義初始化方法( @Bean(initMethod = "init")),執(zhí)行自定義初始化init方法
????????4/applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)執(zhí)行后置處理器后置方法BeanPostProcessor.postProcessAfterInitialization()(bean初始化之后調(diào)用)
??????5.registerDisposableBeanIfNecessary(beanName, bean, mbd); 注冊(cè)Bean的銷毀方法
??7)Bean創(chuàng)建完成后,執(zhí)行g(shù)etSingleton方法將創(chuàng)建的Bean添加到IOC容器中(緩存到singletonObjects(Map集合)中,IOC容器有很多個(gè)map集合,這是其中一個(gè))
Bean生命周期流程圖

spring aop的原理分析
AOP:面向切面的編程,在方法運(yùn)行時(shí),動(dòng)態(tài)將方法切入到其他代碼中運(yùn)行
切面(@Aspect)、切入點(diǎn)(@Pointcut)通知(@Before、@After、@AfterReturning、@AfterThrowing、@Around)
spring注解方式開啟aop功能只需要在配置類上加上@EnableAspectJAutoProxy注解
@Configuration
@EnableAspectJAutoProxy
public class DemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContextionContext = new AnnotationConfigApplicationContext(DemoApplication.class);
}
AOP原理主要通過@EnableAspectJAutoProxy注解來實(shí)現(xiàn)
分析@EnableAspectJAutoProxy
點(diǎn)進(jìn)@EnableAspectJAutoProxy中,發(fā)現(xiàn)@Import(AspectJAutoProxyRegistrar.class),這個(gè)注解作用是把AspectJAutoProxyRegistrar注冊(cè)到容器中
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class) // 把AspectJAutoProxyRegistrar導(dǎo)入到容器中
public @interface EnableAspectJAutoProxy {
...... 忽略部份代碼
}
1、進(jìn)入AspectJAutoProxyRegistrar類
?? 1.這個(gè)類實(shí)現(xiàn)了ImportBeanDefinitionRegistrar,可通過BeanDefinitionRegistry registry手動(dòng)注冊(cè)組件到容器中
?? 2.AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry) 手動(dòng)給容器注冊(cè)一個(gè)AspectJAnnotationAutoProxyCreator組件
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 給容器注冊(cè)一個(gè)AspectJAnnotationAutoProxyCreator類
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
...... 忽略部份代碼
}
2、進(jìn)入上面的registerAspectJAnnotationAutoProxyCreatorIfNecessary()方法,這個(gè)方法最終包裝到registerOrEscalateApcAsRequired()方法來處理
?? 1.注冊(cè)一個(gè)beanName(bean的id)為internalAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator類到容器中
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
......忽略部份代碼
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 傳入的cls為AnnotationAwareAspectJAutoProxyCreator.class
// public static final String AUTO_PROXY_CREATOR_BEAN_NAME ="org.springframework.aop.config.internalAutoProxyCreator";
// 注冊(cè)一個(gè)beanName(bean的id)為internalAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator類到容器中
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
3、最終將AnnotationAwareAspectJAutoProxyCreator類的定義信息注冊(cè)到容器中(beanDefinitionMap(Map集合)中),這個(gè)類是后置處理器的實(shí)現(xiàn)類(后置處理器會(huì)在bean初始化前后做一些處理)。
4、之前講spring啟動(dòng)原理的時(shí)候提到過后置處理器的實(shí)現(xiàn)會(huì)在刷新容器的時(shí)候會(huì)調(diào)用registerBeanPostProcessors(beanFactory),找出這些后置處理器定義信息調(diào)用getBean方法(上面已經(jīng)講過bean的創(chuàng)建流程)進(jìn)行Bean創(chuàng)建并初始化注冊(cè)到容器中然后(保存到容器的beanPostProcessors(Map集合)中)
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
......忽略部份代碼
// AnnotationAwareAspectJAutoProxyCreator的父類實(shí)現(xiàn)了Ordered接口,所以處理的邏輯在這里注冊(cè)
// Next, register the BeanPostProcessors that implement Ordered.
// 注冊(cè)實(shí)現(xiàn)了Ordered接口的BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
// 通過getBean創(chuàng)建并初始化Bean對(duì)象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
// 然后保存到容器的beanPostProcessors的位置中
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
......忽略部份代碼
}
到這里AnnotationAwareAspectJAutoProxyCreator就創(chuàng)建完成了,它屬于InstantiationAwareBeanPostProcessor類型的BeanPostProcessor
spring aop注解使用AOP功能只需要編寫一個(gè)切面類@Aspect,然后指定@Pointcut需要代理的包范圍,再編寫 @Before等通知方法,例如下面代碼
*/
@Component
@Aspect
public class MyAspectJ {
//抽取公共的切入點(diǎn)表達(dá)式
//1、本類引用
//2、其他的切面引用
@Pointcut("execution(public * com.example.demo.aop..*.*(..))")
public void pointCut(){};
//@Before在目標(biāo)方法之前切入;切入點(diǎn)表達(dá)式(指定在哪個(gè)方法切入)
@Before("pointCut()")
public void before(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(""+joinPoint.getSignature().getName()+"運(yùn)行。。。@Before:參數(shù)列表是:{"+ Arrays.asList(args)+"}");
}
@After("pointCut()")
public void after(JoinPoint joinPoint){
System.out.println(""+joinPoint.getSignature().getName()+"結(jié)束。。。@After");
}
//JoinPoint一定要出現(xiàn)在參數(shù)表的第一位
@AfterReturning(value="pointCut()",returning="result")
public void afterReturning(JoinPoint joinPoint,Object result){
System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:運(yùn)行結(jié)果:{"+result+"}");
}
@AfterThrowing(value="pointCut()",throwing="exception")
public void afterThrowing(JoinPoint joinPoint,Exception exception){
System.out.println(""+joinPoint.getSignature().getName()+"異常。。。異常信息:{"+exception+"}");
}
}
// 需要增強(qiáng)的目標(biāo)方法類(這個(gè)類必須在com.example.demo.aop下)
// vp需要增強(qiáng)的目標(biāo)方法
package com.example.demo.aop;
@Component
public class MyAopBean {
public int vp(){
System.out.println("運(yùn)行vp方法");
return 1;
}
}
這里主要分析切面類(MyAspectJ)和需要增強(qiáng)的目標(biāo)方法類(MyAopBean)的創(chuàng)建實(shí)例對(duì)象的過程
MyAspectJ創(chuàng)建實(shí)例對(duì)象過程
MyAspectJ的實(shí)例化過程與上面分析的單實(shí)例Bean實(shí)例過程一致,不同的是開啟AOP切面類(MyAspectJ)在
6.1、調(diào)用Object bean = resolveBeforeInstantiation(beanName, mbdToUse)會(huì)執(zhí)行
AbstractAutoProxyCreator.postProcessBeforeInstantiation(),把MyAspectJ切面類增加到advisedBeans(this.advisedBeans.put(cacheKey, Boolean.FALSE))
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
......
// 因?yàn)锳OP的AnnotationAwareAspectJAutoProxyCreator屬于InstantiationAwareBeanPostProcessor類型的后置處理器
//所以會(huì)進(jìn)行applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
......
}
applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)方法的ibp.postProcessBeforeInstantiation(beanClass, beanName)執(zhí)行的就是AbstractAutoProxyCreator.postProcessBeforeInstantiation()
@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;
}
// isInfrastructureClass(beanClass)會(huì)判斷當(dāng)前bean是否是基礎(chǔ)類型的Advice、Pointcut、Advisor、AopInfrastructureBean或者是否是切面(@Aspect)
//如果是就會(huì)把bean添加到advisedBeans集合中
// 因?yàn)镸yAspectJ屬于@Aspect,所以會(huì)被添加到advisedBeans中
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
......
return null;
}
切面類實(shí)例化的其他步驟與普通Bean的流程一樣
切面類(MyAspectJ)的實(shí)例化過程不同點(diǎn)在于執(zhí)行到了Object bean = resolveBeforeInstantiation(beanName, mbdToUse)時(shí)該Bean會(huì)被保存到advisedBeans中(保存了AOP的增強(qiáng)信息,后面的目標(biāo)方法創(chuàng)建代理對(duì)象需要到這里找到增強(qiáng)的通知方法)
目標(biāo)方法類(MyAopBean)的創(chuàng)建過程
在6.3.4.4調(diào)用initializeBean(beanName, exposedObject, mbd)的applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)執(zhí)行后置處理器的后置方法時(shí),會(huì)執(zhí)行
AbstractAutoProxyCreator.postProcessAfterInitialization()方法
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果需要就進(jìn)行包裝,這個(gè)方法處理創(chuàng)建代理對(duì)象流程
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
進(jìn)入wrapIfNecessary(bean, beanName, cacheKey)方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && 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;
}
// 如果有當(dāng)前Bean所要的增強(qiáng)(通知方法),就創(chuàng)建代理對(duì)象。我們?cè)贛yAspectJ切面類上定義了4個(gè)增強(qiáng)方法(通知方法),這里會(huì)get到,看下圖
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果獲取到通知方法,就創(chuàng)建代理對(duì)象
if (specificInterceptors != DO_NOT_PROXY) {
// 把當(dāng)前目標(biāo)方法類放入advisedBeans中,true表示做了增強(qiáng)處理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 開始創(chuàng)建代理對(duì)象
// spring會(huì)自動(dòng)決定使用JdkDynamicAopProxy(config) jdk動(dòng)態(tài)代理
//或者ObjenesisCglibAopProxy(config) cglib的動(dòng)態(tài)代理來創(chuàng)建
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理對(duì)象
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
1 2 3 4是我們自己定義切面類(MyAspectJ)上的增強(qiáng)方法

目標(biāo)方法類(MyAopBean)的創(chuàng)建過程在6.3.4.4調(diào)用initializeBean(beanName, exposedObject, mbd)的applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)執(zhí)行后置處理器的后置方法時(shí),會(huì)執(zhí)行AbstractAutoProxyCreator.postProcessAfterInitialization()方法創(chuàng)建代理對(duì)象并返回。
這里就把目標(biāo)類的Bean(代理對(duì)象)創(chuàng)建好了,以后獲取這個(gè)Bean時(shí)都是獲取代理對(duì)象。
MyAopBean創(chuàng)建好后,分析目標(biāo)方法vp()是如何執(zhí)行的(是通過責(zé)任鏈模式調(diào)用來執(zhí)行的)
把斷點(diǎn)打到了vp()方法,Step into進(jìn)入了
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
說明這個(gè)intercept攔截目標(biāo)方法的執(zhí)行,做了一些處理
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
......
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 如果沒有增強(qiáng)方法,就執(zhí)行這里(這里是通過反射直接調(diào)用目標(biāo)方法)
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// chain的list有增強(qiáng)的方法,就創(chuàng)建方法的代理并執(zhí)行proceed()
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
1.調(diào)用List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)獲取將要執(zhí)行的目標(biāo)方法攔截器鏈(就是增強(qiáng)方法(通知))
??1.1)獲取并遍歷所有的Advisor(增強(qiáng)器),將其轉(zhuǎn)為Interceptor并返回。
這里獲取到5個(gè)增強(qiáng),一個(gè)默認(rèn)的ExposeInvocationInterceptor 和 4個(gè)自定義的aop通知,如下圖

2.獲取到攔截器鏈后調(diào)用retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();創(chuàng)建CglibMethodInvocation對(duì)象并調(diào)用proceed()觸發(fā)攔截器鏈(org.springframework.aop.framework.ReflectiveMethodInvocation#proceed)
3.分析proceed方法的執(zhí)行
public Object proceed() throws Throwable {
// currentInterceptorIndex 默認(rèn)為-1,每執(zhí)行一次proceed()都會(huì)+1,沒有攔截器(通知方法)或者執(zhí)行最后一個(gè)攔截器執(zhí)行proceed()方法時(shí),都會(huì)執(zhí)行目標(biāo)方法
//this.interceptorsAndDynamicMethodMatchers是一個(gè)list集合,存儲(chǔ)了上面獲取到的5個(gè)攔截器(通知方法)
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// invokeJoinpoint是執(zhí)行目標(biāo)方法
return invokeJoinpoint();
}
// 獲取++this.currentInterceptorIndex坐標(biāo)的攔截器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
}
......忽略部份代碼
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
??3.1)第一次進(jìn)入proceed方法,currentInterceptorIndex為-1,this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);獲取坐標(biāo)為0的通知方法(ExposeInvocationInterceptor 默認(rèn)的增強(qiáng)器)

??3.2)然后走到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this),將增強(qiáng)器轉(zhuǎn)成MethodInterceptor執(zhí)行invoke(this),執(zhí)行的是ExposeInvocationInterceptor.invoke(),發(fā)現(xiàn)調(diào)用的還是mi.proceed()方法(上面?zhèn)鲄⑹莟his,所以這方法還是ReflectiveMethodInvocation#proceed)

??3.3)又回到ReflectiveMethodInvocation#proceed方法,此時(shí)currentInterceptorIndex為0,不等于(5-1),會(huì)繼續(xù)執(zhí)行this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);獲取坐標(biāo)為1的通知方法(AspectJAfterThrowingAdvice(異常通知 @AfterThrowing))

??3.4)然后又走到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this),這次執(zhí)行的是異常通知的invoke,AspectJAfterThrowingAdvice#invoke(),它又會(huì)執(zhí)行mi.proceed()

??3.5)AspectJAfterThrowingAdvice#invoke()調(diào)用mi.proceed()回到ReflectiveMethodInvocation#proceed方法此時(shí)currentInterceptorIndex為1,不等于(5-1),會(huì)繼續(xù)執(zhí)行this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);獲取坐標(biāo)為2的通知方法(AfterReturningAdviceInterceptor (返回通知 @AfterReturning 目標(biāo)方法正常返回之后調(diào)用))

??3.6)然后又走到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this),這次執(zhí)行的是返回通知的invoke,AfterReturningAdviceInterceptor#invoke,它又會(huì)先執(zhí)行mi.proceed()

3.7)AfterReturningAdviceInterceptor#invoke()調(diào)用mi.proceed()回到ReflectiveMethodInvocation#proceed方法此時(shí)currentInterceptorIndex為2,不等于(5-1),會(huì)繼續(xù)執(zhí)行this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);獲取坐標(biāo)為3的通知方法(AspectJAfterAdvice(后置通知 @After 在目標(biāo)方法運(yùn)行結(jié)束之后運(yùn)行之后調(diào)用,不管是否有異常))

3.8)然后又走到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this),這次執(zhí)行的是后置通知的invoke,AspectJAfterAdvice#invoke,它又會(huì)先執(zhí)行mi.proceed()

3.9)AspectJAfterAdvice#invoke()調(diào)用mi.proceed()回到ReflectiveMethodInvocation#proceed方法此時(shí)currentInterceptorIndex為3,不等于(5-1),會(huì)繼續(xù)執(zhí)行this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);獲取坐標(biāo)為4的通知方法(MethodBeforAdivceInterceptor(前置通知 @Before 在目標(biāo)方法運(yùn)行之前調(diào)用))

3.10)然后又走到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this),這次執(zhí)行的是前置通知的invoke,MethodBeforeAdviceInterceptor#invoke,它會(huì)先調(diào)用this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis())執(zhí)行前置通知的方法(@Before)


3.11)執(zhí)行完前置通知的方法后,會(huì)再次調(diào)用mi.proceed(),此時(shí)currentInterceptorIndex為4,等于(5-1),所以會(huì)執(zhí)行invokeJoinpoint()(這個(gè)方法就是執(zhí)行目標(biāo)方法的,通過this.methodProxy.invoke(this.target, this.arguments))


3.12)執(zhí)行完ruturn invokeJoinpoint()(目標(biāo)方法之后),MethodBeforeAdviceInterceptor.invoke()就return了,然后回到調(diào)用AspectJAfterAdvice.invoke((回到上一級(jí)調(diào)用MethodBeforeAdviceInterceptor的方法)),這時(shí)會(huì)調(diào)用invokeAdviceMethod(getJoinPointMatch(), null, null),執(zhí)行后置方法(不管是否目標(biāo)方法有異常都會(huì)執(zhí)行到)


3.13)執(zhí)行完AspectJAfterAdvice.invoke()之后,這時(shí)目標(biāo)方法拋出異常了(int i = 1/0;),AfterReturningAdviceInterceptor#invoke就不會(huì)執(zhí)行this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis())了(如果正常返回就會(huì)執(zhí)行this.advice.afterReturning來調(diào)用返回通知),它會(huì)把異常拋給上一層(AspectJAfterThrowingAdvice),這時(shí)回到
AspectJAfterThrowingAdvice#invoke(回到上一級(jí)調(diào)用AfterReturning的方法),會(huì)調(diào)用invokeAdviceMethod(getJoinPointMatch(), null, ex);執(zhí)行異常通知方法,然后throw ex拋出異常給上一層(ExposeInvocationInterceptor)


3.14)執(zhí)行完異常通知方法,會(huì)回到最早的ExposeInvocationInterceptor增強(qiáng)器方法中,執(zhí)行完finally之后,就會(huì)拋出異常給jvm


AOP目標(biāo)方法執(zhí)行原理分析完畢,使用鏈?zhǔn)秸{(diào)用,從坐標(biāo)為0的增強(qiáng)器一直調(diào)到最后一個(gè)增強(qiáng)器,然后最后一個(gè)增強(qiáng)器執(zhí)行完后,返回上一個(gè)增強(qiáng)器繼續(xù)執(zhí)行操作...直到返回到第一個(gè)增強(qiáng)器執(zhí)行完成,增強(qiáng)了的目標(biāo)方法就執(zhí)行完成
目標(biāo)方法(MyAopBean.vp)執(zhí)行的流程圖

AOP啟動(dòng)總結(jié):
spring容器啟動(dòng)時(shí)調(diào)用refresh()刷新容器(具體spring容器啟動(dòng)的流程請(qǐng)看http://www.itdecent.cn/writer#/notebooks/31229867/notes/54723874/preview
)
- refresh()# invokeBeanFactoryPostProcessors(beanFactory),會(huì)將spring能感知到的(加了注解的)所有Bean的定義信息保存到容器中。(AnnotationAwareAspectJAutoProxyCreator、MyAspectJ、MyAopBean的定義信息都是這時(shí)候注冊(cè)到容器的)
- refresh()# registerBeanPostProcessors(beanFactory)會(huì)創(chuàng)建并初始化后置處理器并注冊(cè)到容器中,因?yàn)锳nnotationAwareAspectJAutoProxyCreator屬于InstantiationAwareBeanPostProcessor類型的后置處理器,所以在這時(shí)會(huì)創(chuàng)建AnnotationAwareAspectJAutoProxyCreator的實(shí)例注冊(cè)到容器中
- refresh()# finishBeanFactoryInitialization(beanFactory) 會(huì)初始化(創(chuàng)建Bean的實(shí)例)所有剩下的單實(shí)例Bean,MyAspectJ類和MyAopBean類在這時(shí)會(huì)創(chuàng)建Bean實(shí)例并保存到容器中