Spring初始化
--- StandardContext --- //org.apache.catalina.core.StandardContext
startInternal -> listenerStart -> listener.contextInitialized(ServletContextListener.contextInitialized)
--- ContextLoaderListener ---
contextInitialized -> initWebApplicationContext -> createWebApplicationContext(Default:XmlWebApplicationContext) -> configureAndRefreshWebApplicationContext -> refresh
--- AbstractApplicationContext ---
refresh
//1.create factory and load bean definition.
obtainFreshBeanFactory
-> refreshBeanFactory
-> createBeanFactory(DefaultListableBeanFactory)
-> loadBeanDefinitions //加載applicationContext文件焊夸,將里面的bean定義轉(zhuǎn)成BeanDefinition肴敛,裝在到BeanFactory beanDefinitionMap
//2.invoke factory processor: Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors
-> postProcessBeanFactory //BeanFactoryPostProcessor桶雀,可以修改bean definitions空执,此動(dòng)作在所有bean初始化之前 //All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans.
//3.register bean processor: Register bean processors that intercept bean creation. 將BeanPostProcessor類型的bean提前加載勋眯、實(shí)例化初始化婴梧,并注冊(cè)下梢,然后在第4步普通bean創(chuàng)建時(shí)執(zhí)行攔截方法:postProcessBefore/AfterInitialization
registerBeanPostProcessors
-> registerBeanPostProcessors
-> getBean (for (String ppName : postProcessorNames); BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);) //go to AbstractBeanFactory.getBean getBean這里會(huì)實(shí)例化BeanPostProcessor
-> beanFactory.addBeanPostProcessor(postProcessor);
//4.instantiate: Instantiate all remaining (non-lazy-init) singletons. 實(shí)例化剩余普通的bean
finishBeanFactoryInitialization(beanFactory);
-> preInstantiateSingletons(beanFactory.preInstantiateSingletons()) //List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); for (String beanName : beanNames) -> getBean(beanName);
-> getBean (for (String beanName : beanNames) { getBean(beanName); }) //go to AbstractBeanFactory.getBean
擴(kuò)展
擴(kuò)展原理:
1、init塞蹭,registerBeanDefinitionParser注冊(cè)BeanDefinition解釋器
2孽江、parse:2.1.element 獲取自定義的配置 2.2.registerBeanDefinition 向registry注冊(cè)BeanDefinition
registry其實(shí)就是factory:DefaultListableBeanFactory,registerBeanDefinition 注冊(cè)beanDefinition番电,后續(xù)在finishBeanFactoryInitialization中會(huì)遍歷所有beanDefinition進(jìn)行實(shí)例化岗屏。
這個(gè)注冊(cè)過程其實(shí)就跟手動(dòng)注解@Component一個(gè)意思,注冊(cè)beanDefinition漱办,之后由工廠進(jìn)行初始化这刷。
--- AbstractXmlApplicationContext ---
loadBeanDefinitions -> XmlBeanDefinitionReader.loadBeanDefinitions -> DefaultBeanDefinitionDocumentReader.registerBeanDefinitions
-> DefaultBeanDefinitionDocumentReader.parseBeanDefinitions -> BeanDefinitionParserDelegate.parseCustomElement
--- BeanDefinitionParserDelegate ---
parseCustomElement -> resolve(String namespaceUri) -> namespaceHandler.init() //NamespaceHandlerSupport -> registerBeanDefinitionParser("xx",new XXBeanDefinitionParser());
-> handler.parse -> XXBeanDefinitionParser.parse -> registry.registerBeanDefinition("xxBeanDefinition",xxBeanDefinition);//解析自定義的配置文件,然后一般會(huì)向registry進(jìn)行注冊(cè)registerBeanDefinition
通過NamespaceHandlerSupport娩井、BeanDefinitionParser完成擴(kuò)展:
public class XXNamespaceHandler extends NamespaceHandlerSupport{
@Override
public void init() {
registerBeanDefinitionParser("annotation-driven",new XXBeanDefinitionParser());
}
}
//XXBeanDefinitionParser 也可以繼承自AbstractSingleBeanDefinitionParser暇屋、AbstractBeanDefinitionParser,原理是類似的洞辣。
public class XXBeanDefinitionParser implements BeanDefinitionParser{
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
//element 配置文件的對(duì)象
RootBeanDefinition xxBeanDefinition = new RootBeanDefinition();
BeanDefinitionRegistry registry = parserContext.getRegistry();
registry.registerBeanDefinition("xxx", xxBeanDefinition);
return xxBeanDefinition;
}
}
創(chuàng)建Bean
//Parse the elements at the root level in the document: "import", "alias", "bean".
--- AbstractBeanFactory ---
getBean
doGetBean
getSingleton
createBean //go to AbstractAutowireCapableBeanFactory.createBean
--- AbstractAutowireCapableBeanFactory ---
createBean
-> resolveBeforeInstantiation -> postProcessBeforeInstantiation (if (bean != null) -> postProcessAfterInitialization)
-> doCreateBean
-> createBeanInstance -> instantiateBean -> BeanUtils.instantiateClass(constructorToUse) -> constructorToUse.newInstance(args)
-> populateBean(postProcessAfterInstantiation -> autowire -> postProcessPropertyValues -> applyPropertyValues)
-> initializeBean
-> invokeAwareMethods(BeanNameAware->setBeanName, BeanClassLoaderAware->setBeanClassLoader, BeanFactoryAware->setBeanFactory)
-> postProcessBeforeInitialization
-> invokeInitMethods(afterPropertiesSet&invokeCustomInitMethod)
-> postProcessAfterInitialization
Bean創(chuàng)建關(guān)鍵流程如下:
createBean
-> postProcessBeforeInstantiation -> return null -> createBeanInstance -> postProcessAfterInstantiation -> postProcessBeforeInitialization -> invokeInitMethods -> postProcessAfterInitialization -> return bean
-> postProcessBeforeInstantiation -> not null -> postProcessAfterInitialization -> return bean
從這里看可以看到咐刨,在這個(gè)過程有多個(gè)可以執(zhí)行攔截的地方,這些攔截也正是Spring作為一個(gè)框架的優(yōu)秀之處扬霜,因?yàn)樵跀r截的地方可以進(jìn)行各種增強(qiáng)定鸟,使得其擁有良好的擴(kuò)展性:
InstantiationAwareBeanPostProcessor: postProcessBeforeInstantiation/postProcessAfterInstantiation/postProcessPropertyValues 作用于實(shí)例化階段
BeanPostProcessor: postProcessBeforeInitialization/postProcessAfterInitialization 作用于初始化階段
1、createBean
1.1 resolveBeforeInstantiation
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); //applyBeanPostProcessorsBeforeInstantiation
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); //applyBeanPostProcessorsAfterInitialization
}
...
return bean;
1.2 applyBeanPostProcessorsBeforeInstantiation
//invoking their postProcessBeforeInstantiation methods. 調(diào)用postProcessBeforeInstantiation著瓶,這個(gè)方法在bean實(shí)例化之前執(zhí)行
//Any returned object will be used as the bean instead of actually instantiating the target bean.
//A null return value from the post-processor will result in the target bean being instantiated.
//若返回了非空對(duì)象联予,則直接被當(dāng)做bean,替代后續(xù)真正實(shí)例化的bean材原;若返回是空的沸久,將繼續(xù)調(diào)用實(shí)際的實(shí)例化方法
//即若在這里執(zhí)行攔截返回了非空對(duì)象,后續(xù)bean的實(shí)例化將跳過华糖,直接跳轉(zhuǎn)執(zhí)行bean的初始化后置操作postProcessAfterInitialization麦向,然后直接返回
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); //InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
return null;
2瘟裸、doCreateBean
2.1 createBeanInstance(beanName, mbd, args); //創(chuàng)建對(duì)象(實(shí)例化)
2.2 populateBean(beanName, mbd, instanceWrapper); //填充對(duì)象屬性
2.3 initializeBean //初始化
2.2 populateBean
2.2.1 postProcessAfterInstantiation
//This is the ideal callback for performing field injection on the given bean instance. 是一個(gè)執(zhí)行字段注入的回調(diào)方法客叉。若返回false,將不再執(zhí)行后續(xù)的字段注入话告。
//如果返回false兼搏,將不再給bean設(shè)置屬性。此接口目前三個(gè)實(shí)現(xiàn)都是無任何操作沙郭,僅僅只是返回了true佛呻。
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
if (!continueWithPropertyPopulation) {
return;
}
2.2.2 autowire
PropertyValues pvs = mbd.getPropertyValues();
autowireByName(beanName, mbd, bw, newPvs); //加載屬性依賴的bean
autowireByType(beanName, mbd, bw, newPvs);
2.2.3 postProcessPropertyValues
//Post-process the given property values before the factory applies them to the given bean. Also allows for replacing the property values to apply
//對(duì)屬性值進(jìn)行后置處理,允許替換要應(yīng)用的屬性值
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
2.2.4 applyPropertyValues
2.3 initializeBean
2.3.1 invokeAwareMethods
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
2.3.2 applyBeanPostProcessorsBeforeInitialization //postProcessBeforeInitialization
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
2.3.3 invokeInitMethods //afterPropertiesSet, invokeCustomInitMethod
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean...) {
((InitializingBean) bean).afterPropertiesSet();
}
invokeCustomInitMethod
2.3.4 applyBeanPostProcessorsAfterInitialization
result = beanProcessor.postProcessAfterInitialization(result, beanName);
AOP
核心:AbstractAutoProxyCreator implements SmartInstantiationAwareBeanPostProcessor, InstantiationAwareBeanPostProcessor,
BeanPostProcessor
原理:postProcessBefore/AfterInstantiation, postProcessBefore/AfterInitialization病线,在Bean的創(chuàng)建或初始化的前后攔截吓著,實(shí)現(xiàn)代理鲤嫡。
核心類:AbstractAutoProxyCreator、AnnotationAwareAspectJAutoProxyCreator
1绑莺、配置AspectJ:若需要AspactJ支持暖眼,需要添加配置,其實(shí)現(xiàn)對(duì)應(yīng) AnnotationAwareAspectJAutoProxyCreator纺裁,添加配置有2中方式
1.1 配置文件文件
<aop:aspectj-autoproxy proxy-target-class="true"/>
1.2 AopConfigUtils
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary
2诫肠、構(gòu)建Advisor
AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
2.1 postProcessBeforeInstantiation 以這個(gè)方法為入口構(gòu)建Advisor(但這里并沒有做攔截)
//AbstractAutoProxyCreator
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { //Advisor所在的類跳過,不執(zhí)行攔截
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName); //其他類執(zhí)行代理創(chuàng)建欺缘,一般未指定targetSource栋豫,這里都不會(huì)執(zhí)行代理創(chuàng)建
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null; //未自定義TargetSource的,一般也直接返回null
}
//AspectJAwareAdvisorAutoProxyCreator
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors(); //這里會(huì)去查找所有的Advisor谚殊,即找到所有增強(qiáng)方法
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) { //Advisor所在的類跳過丧鸯,不執(zhí)行攔截
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
2.2 Advisor的構(gòu)造過程
2.2.1 查找所有bean,找出@Aspect切面的bean
buildAspectJAdvisors - BeanFactoryAspectJAdvisorsBuilder
for (String beanName : beanNames) {
if (this.advisorFactory.isAspect(beanType)) { //isAspect: hasAspectAnnotation(clazz) && !compiledByAjc(clazz)
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
}
}
2.2.2 找到所有的Advisor方法
getAdvisors - ReflectiveAspectJAdvisorFactory
for (Method method : getAdvisorMethods(aspectClass)) {
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
//獲取所有方法络凿,排除Pointcut注解的方法
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new LinkedList<Method>();
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}
});
Collections.sort(methods, METHOD_COMPARATOR);
return methods;
}
2.2.3 找到帶@Around @Before等注解的方法骡送,并將其包裝成Advisor
getAdvisor -> getPointcut -> findAspectJAnnotationOnMethod
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
Class<?>[] classesToLookFor = new Class<?>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
for (Class<?> c : classesToLookFor) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c); //獲取PointCut配置,如@Around("execution(* com.xx.xx.x..*.*(..)) || @annotation(com.xx.xx.xx.XXAnnotation)")
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
3.3 代理的創(chuàng)建 postProcessAfterInitialization
再回顧一遍這個(gè)流程:
refresh -> finishBeanFactoryInitialization -> preInstantiateSingletons -> getBean -> doGet.. -> createBean .. -> createBeanInstance(AbstractAutowireCapableBeanFactory) 這里就已經(jīng)實(shí)例化完成絮记,bean已經(jīng)創(chuàng)建了 -> populateBean
-> initializeBean -> applyBeanPostProcessorsAfterInitialization -> beanProcessor.postProcessAfterInitialization(AnnotationAwareAspectJAutoProxyCreator)
-> postProcessAfterInitialization(AbstractAutoProxyCreator) -> wrapIfNecessary -> getAdvicesAndAdvisorsForBean(查找當(dāng)前bean是否需要增強(qiáng)) -> AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)
-> createProxy -> proxyFactory.getProxy -> createAopProxy(DefaultAopProxyFactory) -> getProxy (CglibAopProxy)
真正代理創(chuàng)建并不是在postProcessBeforeInstantiation摔踱,而是postProcessAfterInitialization,所以真正攔截怨愤,將bean替換成代理對(duì)象是在postProcessAfterInitialization方法做的派敷。
postProcessAfterInitialization 一般的實(shí)現(xiàn),如果不做代理撰洗,就直接返回bean 就可以篮愉。
wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (specificInterceptors != DO_NOT_PROXY) {
Object proxy = createProxy;
return proxy; //返回的代理對(duì)象替換真正的bean
}
return bean;
}
DefaultAopProxyFactory
createAopProxy:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { //指定了proxy-target-class=true,或hasNoUserSuppliedProxyInterfaces 即當(dāng)前類沒有實(shí)現(xiàn)接口差导,則使用cglib
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config); //cglib
}
else {
return new JdkDynamicAopProxy(config); //jdk
}
}
CglibAopProxy
getProxy
Enhancer enhancer = createEnhancer();
enhancer.setSuperclass(proxySuperClass); //targetClass
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
createProxyClassAndInstance