Spring初始化過程到AOP
初始化過程
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory ();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
// ...
}
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
-> AbstractRefreshableApplicationContext#refreshBeanFactory()
get a beanFactory
(DefaultListableBeanFactory
)
-> loadBeanDefinitions(beanFactory)
-> AbstractXmlApplicationContext#loadBeanDefinitions
, XmlBeanDefinitionReader
, loadBeanDefinition...(not yet instantiate)
registerBeanPostProcessors(beanFactory)
-> 註冊BPP,其中就包含AOP的BPPAbstractAutoProxyCreator
,註意BPP是not-lazy-init的
finishBeanFactoryInitialization(beanFactory);
實例化非lazy-init的bean
-> DefaultListableDeanFactory#preInstantiateSingletons()
-> getBean(beanName)
-> AbstractBeanFactory#getBean(beanName)
-> doGetBean(name, null, null, false)
-> getSingleton
-> createBean
-> AbstractAutowiredCapableBeanFactory#createBean
-> doCreateBean
-> populateBean
-> initializeBean
-> applyBeanPostProcessorsBeforeInitialization
-> invokeInitMethods
-> applyBeanPostProcessorsAfterInitialization
-> getBeanPostProcessors()
然後對每個bean挨個調用bpp的postProcessAfterInitialization
方法,對於AOP,在其中就會有判定是否需要包裝、是否需要生成代理等操作,最後生成一個代理(這部分就是AOP的代碼了)
AOP創建代理
Spring默認會加載AbstractAutoProxyCreator這個Bean(是一個BPP)
AbstractAutoProxyCreator#postProcessAfterInitialization
-> 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;
}
getAdvicesAndAdvisorsForBean
方法找到所有的攔截器,調用createProxy
方法生成代理。
生成Advisor[]
設置到ProxyFactory
中,然後調用ProxyFactory#getProxy
方法獲取代理(JdkDynamicAopProxy和CglibAopProxy
)。其中在生成Advisors是一個表復雜的過程,涉及匹配切點、包裝生成通知(AspectJPointcutAdvisor
.)
ProxyFactor extends ProxyCreatorSupport extends AdvisedSupport
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
ProxyFactory
以自身為參數,因為把Advisors
設置進去了,生成代理時就可以拿到了。生成AopProxy
(CglibAopProxy
或者JdkDynamicAopProxy
的構造參數需要AdvisedSupport
)。
對於不需要包裝(攔截)的方法,有一個攔截器是ExposeInvocationInterceptor
。
在代理的invoke方法裏,會先從AdvisedSupport
中獲取到攔截器鏈,最後包裝成一個MethodInvocation
(ReflectiveMethodInvocation
)調用其proceed
方法。
關鍵是proceed
這個方法,會遞歸調用其中每一個interceptor,這裏的this就是ReflectiveMethodInvocation
,然後在interceptor的invoke方法裏,有前置/後置/環繞等邏輯,或者沒有邏輯(ExposeInvocationInterceptor
是第一個攔截器),參數是MethodInvocation
,然後再調用mi的proceed方法,回到ReflectiveMethodInvocation
中繼續處理,攔截器鏈調完之後就會反射調用返回。此處有點繞,需要多看幾遍代碼。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
攔截器接口InvocationInterceptor
,前置後置等邏輯都實現了該接口。
AspectJAfterAdvice
MethodBeforeAdviceInterceptor
AspectJAroundAdvice
等等
Spring初始化過程到AOP