标签:前置 sed aspect dea 反射 rtu iat vat tee
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的代码了)
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
等等
标签:前置 sed aspect dea 反射 rtu iat vat tee
原文地址:https://www.cnblogs.com/dirac/p/9219904.html