spring中bean的创建顺序

解答以下疑惑:

 

  • Spring配置文件里bean,究竟是按什么样的顺序加载呢?
  • Spring项目在部署时,究竟创建了多少各beanFactory呢?按什么顺序创建?

 

 

长话短说,总结成如下几点:

 

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)。

因此,若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,即使被放置在最后面,也会先加载哦。这种设计还是挺人性化的^_^

参考链接:http://blog.****.net/caihaijiang/article/details/35552859

spring中bean的创建顺序

 

spring中bean的创建顺序

 

Rule4:

component-scan生成的bean的默认id是类名(首字母小写),例如testService1。

<bean>标签生成的bean的默认id是:包名.类名#数字,例如qk.spring.beanFactory.service1.TestService1#0

如果component-scan和bean标签生成的bean有冲突(即bean的id相同),并且都是单例(默认是单例),那么不会重复创建,只保留最先创建出来的那个。

 

 

Rule5:

创建BeanFactory时,按照如下顺序:

(见AbstractAutowireCapableBeanFactory#initializeBean(…)。里面分为AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization(…)和AbstractAutowireCapableBeanFactory#postProcessObjectFromFactoryBean(…))

1)创建BeanFactoryPostProcessor;

2)创建BeanPostProcessor;

3)注册内置的BeanPostProcessor,ApplicationContextAwareProcessor(见AbstractApplicationContext#prepareBeanFactory(…)),ServletContextAwareProcessor见(AbstractRefreshableWebApplicationContext#postProcessBeanFactory(…));

4)执行BeanFactoryPostProcessor(可能会add一些beanPostProcessor);

5)注册配置文件中的BeanPostProcessor(如top代理,config);

6)执行beanPostProcessor。

 

 

Rule6:单个bean加载过程

按照如下顺序:

1)构造函数;

2)BeanPostProcessor#postProcessBeforeInitialization(…);

3)设置property;

4)InitializingBean#afterPropertiesSet();

5)BeanPostProcessor#postProcessAfterInitialization(…);

6)FactoryBean#getObject()的顺序构造bean实例。