解答以下疑惑:
长话短说,总结成如下几点:
Rule1:
首先读取WEB-INF/web.xml文件,该文件内一般会配置spring-config和spring-mvc。按顺序加载对应的xml文件。
Rule2:
若web.xml中还有除springmvc和默认的servlet之外的servlet(如servlet-test),那么这些servlet会按照定义的顺序执行,但一定是在默认servlet之后,springmvc之前执行,并且,若这些servlet都会分别对应一个ApplicationContext,当然也意味着分别拥有一个beanFactory。这些ApplicationContext(包括springmvc的那个),他们的parent ApplicationContext均是默认servlet对应的那个ApplicationContext(Root ApplicationContext)。默认的servlet,是通过参数contextConfigLocation来指定一个xml文件。
因此,若springmvc里的某个Controller尝试通过auto wire注解来注入servlet-test里面的service,那么在运行时会抛出”Could not autowire field …”异常,因为spring从springmvc那个servlet中的beanFactory(包括其父beanFactory)中找不到对应的bean。
Rule3:
在加载某个包含bean的xml文件时,按照bean的类型1)BeanFactoryPostProcessor类的bean;2)BeanPostProcessor类的bean;3)普通bean,包括import进来的(bean标签和scan标签指定的);的顺序进行加载。同类型的bean按照定义顺序加载。所有bean默认是单例的。
因此,对于BeanFactoryPostProcessor和BeanPostProcessor类型的bean,即使被放置在最后面,也会先加载哦。这种设计还是挺人性化的^_^
Rule4:
component-scan生成的bean的默认id是类名(首字母小写),例如testService1。
如果component-scan和bean标签生成的bean有冲突(即bean的id相同),并且都是单例(默认是单例),那么不会重复创建,只保留最先创建出来的那个,同一个属性的话,后续的会覆盖前面的。
Rule5:
创建BeanFactory时,按照如下顺序(beanpostprocessor不会处理beanFactory,虽然他也是个bean)):
(见AbstractAutowireCapableBeanFactory#initializeBean(…)。里面分为AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization(…)和AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean(…))
0)创建beanFactory,并尽可能初始化,此时普通bean还未创建;
1)创建spring自己的部分BeanPostProcessor;
2)创建并执行BeanFactoryPostProcessor(包括自定义的);
3)创建并注册剩余的内置BeanPostProcessor,ApplicationContextAwareProcessor(见AbstractApplicationContext#prepareBeanFactory(…)),ServletContextAwareProcessor见(AbstractRefreshableWebApplicationContext#postProcessBeanFactory(…));
4)创建并注册自定义的BeanPostProcessor(如top代理,config)(AbstractApplicationContext#refresh());
5)创建普通bean(同时应用bean post processor)。
Rule6:单个bean加载过程
按照如下顺序:
1)构造函数;
2)BeanPostProcessor#postProcessBeforeInitialization(…);
3)设置property;
4)InitializingBean#afterPropertiesSet();
5)BeanPostProcessor#postProcessAfterInitialization(…);
6)FactoryBean#getObject()的顺序构造bean实例。
这里是样例project