zoukankan      html  css  js  c++  java
  • 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......
  • 相关阅读:
    CF1202F You Are Given Some Letters...
    CF1178E Archaeology
    PTA (Advanced Level) 1005 Spell It Right
    PTA (Advanced Level) 1004 Counting Leaves
    Qt5——从零开始的Hello World教程(Qt Creator)
    PTA (Advanced Level) 1003 Emergency
    PTA (Advanced Level) 1002 A+B for Polynomials
    HDU 1272 小希的迷宫
    FZU 2150 Fire Game
    HihoCoder
  • 原文地址:https://www.cnblogs.com/LOVE0612/p/9855585.html
Copyright © 2011-2022 走看看