一直对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的顺序的更多相关文章

  1. Spring 创建bean的模式

    在默认情况下,spring创建bean是单例模式 scope="singleton ",还有一种方式为多例模式[prototype]     scope          sing ...

  2. spring创建bean的三种方式

    spring创建bean的三种方式: 1通过构造方法创建bean(最常用) 1.1 spring默认会通过无参构造方法来创建bean,如果xml文件是这样配置,则实体类中必须要有无参构造方法,无参构造 ...

  3. spring创建bean模式singleton与prototype的区别

    spring 创建bean有单例模式(singleton)和原始模型模式(prototype)这两种模式. 在默认的情况下,Spring中创建的bean都是单例模式的(注意Spring的单例模式与Go ...

  4. spring 创建Bean最全实现方法

    创建bean方式,spring创建bean的方式包含:自动注入方式和人工注入方式.分别为:1)xml 配置化方式  2)@bean注解注入方式3)@Component方式 4)接口注入方式 5)imp ...

  5. Spring 创建Bean的6种方式

    前言 本文讲解了在Spring 应用中创建Bean的多种方式,包括自动创建,以及手动创建注入方式,实际开发中可以根据业务场景选择合适的方案. 方式1: 使用Spring XML方式配置,该方式用于在纯 ...

  6. spring创建bean异常

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappi ...

  7. Spring创建Bean的过程Debug

    目录 Spring流程Debug 1.1 Spring测试环境搭建 1.2 Debug容器创建过程 1.3 AbstractApplicationContext的refresh()包含的13个方法分析 ...

  8. []Spring创建Bean的过程

    1. beans包提供了以编程方式管理和操作bean的基本功能,而context包增加了ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory的功能. 2. co ...

  9. Spring 创建bean的时机

    默认在启动spring容器的时候,spring容器配置文件中的类就已经创建完成对象了        在<bean>中添加属性lazy-init,默认值为false.    true  在c ...

随机推荐

  1. 第2节 网站点击流项目(下):7、hive的级联求和

    一.hive级联求和的简单例子: create table t_salary_detail(username string,month string,salary int)row format del ...

  2. JS - 判断字符串某个下标的值

    <html><body> <script type="text/javascript"> var str="0123456789!&q ...

  3. 页面的html调试

    点击页面按下键盘的F12,或者鼠标右键选择检查(N) 会弹出一个窗口,这个窗口就是调试窗口 如上图所示,第一个图标是标签元素选择器,点击使用后,在页面上移动,会在Elements的区域找到你鼠标选中的 ...

  4. 036、Java中三目运算符的使用

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  5. 二、Vue组件(component):组件的相互引用、通过props实现父子组件互传值

    一.组件各部分说明及互相引用 1.一个vue组件由三个部分组成 Template 只能存在一个根元素 2.Script 3.Style scoped:样式只在当前组件内生效 1.1 组件的基本引用代码 ...

  6. I0.0 上升边沿 清空 MW10~MW58 联系多个知识点融合

    编写程序 在I1.2 的上升边沿 触发 MW8+1的程序 实现方式1 M1.1 为中间变量 对应的STL语句表 执行结果 OK 已经仿真 . 现在尝试第2种方法 实现方式2: M1.1也是中间变量 S ...

  7. 使用pip install jupyter报错处理办法及修改Jupyter默认加载路径的方法

    1.配置python环境之后想使用Jupyter,网上查看可以使用pip install Jupyter安装,执行命令行后正常安装,安装到一半以后报错,如图1.2 图1 图2 2.发现是安装过程中安装 ...

  8. python csv

    Python 读取csv的某行 Python 读取csv的某列 Python写了一个可以提取csv任一列的代码,欢迎使用.Github链接 两个list写入csv文件 column1,column2 ...

  9. js加密(十四)mail.yw.gov.cn/ RSA

    1. url: http://mail.yw.gov.cn/ 2. target:登录js 3. 简单分析: 寻找加密js: 3.1 直接寻找加密的参数p是不好找的,所以我们试着去寻找一些更明显的参数 ...

  10. javascript中window.open()与window.location.href

    1.window.location是window对象的属性,而window.open是window对象的方法    window.location是你对当前浏览器窗口的URL地址对象的参考!      ...