Spring创建Bean的顺序
一直对Spring创建bean的顺序很好奇,现在总算有时间写个代码测试一下。不想看过程的小伙伴可以直接看结论
目录结构:

其中:bean4、bean5包下的class没有注解@Component,测试过程中,这两个包的class会直接通过<bean class="XXXXX"/>的方式创建。bean1、bean2、bean3包下的class注解了@Component,以便component-scan扫描。另外,bean创建之间没有依赖关系,例如bean1的创建不依赖于其他bean。
applicationContext1.xml
<bean class="com.luych.test.springBeanCreateOrderTest.bean5.Bean5_2"/>
<context:component-scan base-package="com.luych.test.springBeanCreateOrderTest.bean2" />
<bean class="com.luych.test.springBeanCreateOrderTest.bean5.Bean5_1"/>
applicationContext2.xml
<bean class="com.luych.test.springBeanCreateOrderTest.bean4.Bean4_1"/>
<context:component-scan base-package="com.luych.test.springBeanCreateOrderTest.bean1" />
<bean class="com.luych.test.springBeanCreateOrderTest.bean4.Bean4_2"/>
springMVC-servlet.xml
<context:component-scan base-package="com.luych.test.springBeanCreateOrderTest.bean3" />
web.xml
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springMVC-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext*.xml
</param-value>
</context-param>
运行结果
class com.luych.test.springBeanCreateOrderTest.bean5.Bean5_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean2.Bean2_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean2.Bean2_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean5.Bean5_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean4.Bean4_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean1.Bean1_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean1.Bean1_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean4.Bean4_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean3.Bean3_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean3.Bean3_2 has been created
结论一:
1. 在web.xml中,ContextLoaderListener和DispatcherServlet的书写顺序不会影响相应的xml文件加载顺序。ContextLoaderListener中的xml先加载,DispatcherServlet中的xml后加载。
2. ContextLoaderListener中如果contextConfigLocation通过模糊匹配到多个xml文件时,xml按照文件命名顺序加载。但是如果contextConfigLocation逐个指定了具体加载某个xml,则会按照其指定顺序加载。
本例中可以改为(注意下面代码中蓝色部分):
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext2.xml,classpath*:applicationContext1.xml
</param-value>
</context-param>
则其加载顺序为:
class com.luych.test.springBeanCreateOrderTest.bean4.Bean4_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean1.Bean1_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean1.Bean1_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean4.Bean4_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean5.Bean5_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean2.Bean2_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean2.Bean2_2 has been created
class com.luych.test.springBeanCreateOrderTest.bean5.Bean5_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean3.Bean3_1 has been created
class com.luych.test.springBeanCreateOrderTest.bean3.Bean3_2 has been created
3. 同一个spring的xml文件中,bean的加载顺序按照书写顺序加载
4. 通过component-scan扫描的方式加载bean,在扫描范围内按照class的命名顺序加载
以上的测试过程中,bean的创建是没有依赖关系的,那么如果bean之间的创建存在依赖关系,则被依赖的bean会被优先创建。但是如果存在相互依赖的情况,则会发生异常。
例如:
@Component
public class Bean2_1 { private final Bean2_2 bean2_2; @Autowired
public Bean2_1(Bean2_2 bean2_2) {
this.bean2_2 = bean2_2;
System.out.println(Bean2_1.class + " has been created");
}
}
@Component
public class Bean2_2 { private final Bean2_1 bean2_1; @Autowired
public Bean2_2(Bean2_1 bean2_1) {
this.bean2_1 = bean2_1;
System.out.println(Bean2_2.class + " has been created");
}
}
异常信息:
Error creating bean with name 'bean2_1' defined in file......
Spring创建Bean的顺序的更多相关文章
- Spring 创建bean的模式
在默认情况下,spring创建bean是单例模式 scope="singleton ",还有一种方式为多例模式[prototype] scope sing ...
- spring创建bean的三种方式
spring创建bean的三种方式: 1通过构造方法创建bean(最常用) 1.1 spring默认会通过无参构造方法来创建bean,如果xml文件是这样配置,则实体类中必须要有无参构造方法,无参构造 ...
- spring创建bean模式singleton与prototype的区别
spring 创建bean有单例模式(singleton)和原始模型模式(prototype)这两种模式. 在默认的情况下,Spring中创建的bean都是单例模式的(注意Spring的单例模式与Go ...
- spring 创建Bean最全实现方法
创建bean方式,spring创建bean的方式包含:自动注入方式和人工注入方式.分别为:1)xml 配置化方式 2)@bean注解注入方式3)@Component方式 4)接口注入方式 5)imp ...
- Spring 创建Bean的6种方式
前言 本文讲解了在Spring 应用中创建Bean的多种方式,包括自动创建,以及手动创建注入方式,实际开发中可以根据业务场景选择合适的方案. 方式1: 使用Spring XML方式配置,该方式用于在纯 ...
- spring创建bean异常
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappi ...
- Spring创建Bean的过程Debug
目录 Spring流程Debug 1.1 Spring测试环境搭建 1.2 Debug容器创建过程 1.3 AbstractApplicationContext的refresh()包含的13个方法分析 ...
- []Spring创建Bean的过程
1. beans包提供了以编程方式管理和操作bean的基本功能,而context包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory的功能. 2. co ...
- Spring 创建bean的时机
默认在启动spring容器的时候,spring容器配置文件中的类就已经创建完成对象了 在<bean>中添加属性lazy-init,默认值为false. true 在c ...
随机推荐
- 第2节 网站点击流项目(下):7、hive的级联求和
一.hive级联求和的简单例子: create table t_salary_detail(username string,month string,salary int)row format del ...
- JS - 判断字符串某个下标的值
<html><body> <script type="text/javascript"> var str="0123456789!&q ...
- 页面的html调试
点击页面按下键盘的F12,或者鼠标右键选择检查(N) 会弹出一个窗口,这个窗口就是调试窗口 如上图所示,第一个图标是标签元素选择器,点击使用后,在页面上移动,会在Elements的区域找到你鼠标选中的 ...
- 036、Java中三目运算符的使用
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 二、Vue组件(component):组件的相互引用、通过props实现父子组件互传值
一.组件各部分说明及互相引用 1.一个vue组件由三个部分组成 Template 只能存在一个根元素 2.Script 3.Style scoped:样式只在当前组件内生效 1.1 组件的基本引用代码 ...
- I0.0 上升边沿 清空 MW10~MW58 联系多个知识点融合
编写程序 在I1.2 的上升边沿 触发 MW8+1的程序 实现方式1 M1.1 为中间变量 对应的STL语句表 执行结果 OK 已经仿真 . 现在尝试第2种方法 实现方式2: M1.1也是中间变量 S ...
- 使用pip install jupyter报错处理办法及修改Jupyter默认加载路径的方法
1.配置python环境之后想使用Jupyter,网上查看可以使用pip install Jupyter安装,执行命令行后正常安装,安装到一半以后报错,如图1.2 图1 图2 2.发现是安装过程中安装 ...
- python csv
Python 读取csv的某行 Python 读取csv的某列 Python写了一个可以提取csv任一列的代码,欢迎使用.Github链接 两个list写入csv文件 column1,column2 ...
- js加密(十四)mail.yw.gov.cn/ RSA
1. url: http://mail.yw.gov.cn/ 2. target:登录js 3. 简单分析: 寻找加密js: 3.1 直接寻找加密的参数p是不好找的,所以我们试着去寻找一些更明显的参数 ...
- javascript中window.open()与window.location.href
1.window.location是window对象的属性,而window.open是window对象的方法 window.location是你对当前浏览器窗口的URL地址对象的参考! ...