• 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......
  • 相关阅读:
    简单学习tar命令
    方向
    简单使用ubuntu
    双网卡同时上内外网
    emacs学习中
    IE8的开发者工具
    emacs编辑html
    推荐一款数据恢复软件EasyRecovery
    慢慢的乐趣
    关于一个汽车调度的排车问题
  • 原文地址:https://www.cnblogs.com/LOVE0612/p/9855585.html
Copyright © 2020-2023  润新知