Spring的bean创建顺序

解答以下疑惑:

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


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

Rule1

首先读取WEB-INF/web.xml文件,该文件内一般会配置spring-configspring-mvc。按顺序加载对应的xml文件。


Rule2

web.xml中还有除springmvc和默认的servlet之外的servlet(如servlet-test),那么这些servlet会按照定义的顺序执行,但一定是在默认servlet之后,springmvc之前执行,并且,若这些servlet都会分别对应一个ApplicationContext,当然也意味着分别拥有一个beanFactory。这些ApplicationContext(包括springmvc的那个),他们的parent ApplicationContext均是默认servlet对应的那个ApplicationContextRoot ApplicationContext)。默认的servlet,是通过参数contextConfigLocation来指定一个xml文件。

因此,若springmvc里的某个Controller尝试通过auto wire注解来注入servlet-test里面的service,那么在运行时会抛出”Could not autowire field …”异常,因为springspringmvc那个servlet中的beanFactory(包括其父beanFactory)中找不到对应的bean


Rule3

在加载某个包含beanxml文件时,按照bean的类型1BeanFactoryPostProcessor类的bean2BeanPostProcessor类的bean3)普通bean,包括import进来的(bean标签和scan标签指定的);的顺序进行加载。同类型的bean按照定义顺序加载。所有bean默认是单例的。

因此,对于BeanFactoryPostProcessorBeanPostProcessor类型的bean,即使被放置在最后面,也会先加载哦。这种设计还是挺人性化的^_^


Rule4

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

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

如果component-scanbean标签生成的bean有冲突(即beanid相同),并且都是单例(默认是单例),那么不会重复创建,只保留最先创建出来的那个,同一个属性的话,后续的会覆盖前面的。


Rule5:

创建BeanFactory时,按照如下顺序(beanpostprocessor不会处理beanFactory,虽然他也是个bean)):

见(org.springframework.context.support.AbstractApplicationContext

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

0)创建beanFactory,并尽可能初始化,此时普通bean还未创建;

1)创建spring自己的部分BeanPostProcessor;

2)创建并执行BeanFactoryPostProcessor(包括自定义的)

3)创建并注册剩余的内置BeanPostProcessorApplicationContextAwareProcessor(见AbstractApplicationContext#prepareBeanFactory(…)),ServletContextAwareProcessor见(AbstractRefreshableWebApplicationContext#postProcessBeanFactory(…));

4)创建并注册自定义的BeanPostProcessor(如top代理,config)(AbstractApplicationContext#refresh());

5)创建普通bean(同时应用bean post processor)。





Rule6:单个bean加载过程

按照如下顺序:

1)构造函数;

2BeanPostProcessor#postProcessBeforeInitialization(…)

3)设置property

4InitializingBean#afterPropertiesSet();

5BeanPostProcessor#postProcessAfterInitialization(…)

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



这里是样例project


  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值