Spring初始化过程到AOP
Posted dirac
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的主要内容,如果未能解决你的问题,请参考以下文章