zoukankan      html  css  js  c++  java
  • Spring-IOC XML 配置多个相同 ID 的 bean 加载分析

    我们现在仍以 xml 中配置 bean 的方式来 使用 Spring ,不考虑注解和扫包

    配置相同id 的bean

    定义一个 beanTransactionManager

    /**
     * @author maple 2018.09.10 下午10:27
     */
    public class TransactionManager {
        private static int counter = 0;
    
        private String beanName;
    
    
        public void setBeanName(String beanName) {
            this.beanName = beanName;
        }
    
        public TransactionManager() {
            System.out.println("===========> ===========>  TransactionManager counter :" + (++counter));
        }
    
        public void hello() {
            System.out.println("===========> ===========>  hello world, counter is " + counter + ", name is " + beanName);
        }
    }
    
    
    

    TransactionManager 有一个静态变量 counter 可以判断该类被实例化了几次

    Spring 管理 bean

    <bean id="manager" class="com.hzways.multiply.TransactionManager">
            <property name="beanName" value="master"/>
    </bean>
    
    <bean id="manager" class="com.hzways.multiply.TransactionManager">
            <property name="beanName" value="master"/>
     </bean>
    

    照这种方式配置,spring 会直接报错,在同一个xml文件下,这样的配置是不允许的。

    Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'manager' is already used in this <beans> element
    Offending resource: URL [file:/Users/maple/developer/spring-learning/maple-spring/maple-ioc/target/classes/services3.xml]
    

    甚至 idea 都会进行提示
    idea提示

    然而,我们有其他办法让Spring 能够去接纳 在 xml 中 配置 多个相同 的 bean 。

    使用 import 的 方式 配置相同 id 的 bean

    我们可以在 service.xml 中 配置 一个 bean ,并使用 import 的形式 导入另一个 spring 的xml 配置文件

    service.xml

    <bean id="manager" class="com.hzways.multiply.TransactionManager">
            <property name="beanName" value="master"/>
    </bean>
    
    
    <import resource="classpath*:services2.xml"/>
    

    services2.xml

    <bean id="manager" class="com.hzways.multiply.TransactionManager">
            <property name="beanName" value="slave"/>
    </bean>
    

    通过这样的配置后,Spring不会报错,启动主程序。

    public class Main {
    
        public static void main(String[] args) throws InterruptedException {
            ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath*:services3.xml");
            applicationContext.start();
    
    
            TransactionManager helloWorld = applicationContext.getBean(TransactionManager.class);
    
            helloWorld.hello();
    
            Thread.sleep(Long.MAX_VALUE);
    
        }
    }
    

    控制台打印如下:

    ===========> ===========>  TransactionManager counter :1
    ===========> ===========>  hello world, counter is 1, name is slave
    

    分析控制台日志发现,TransactionManager 类 只被加载了一次,而且加载的是从 service2.xml 里面定义的bean

    我们调换顺序,把 import 放在 bean 定义之上,再进行测试。

    
        <import resource="classpath*:services3-bean.xml"/>
    
        <bean id="manager" class="com.hzways.multiply.TransactionManager">
            <property name="beanName" value="master"/>
        </bean>
    
    
    

    这次程序果然打的是 master

    ===========> ===========>  TransactionManager counter :1
    ===========> ===========>  hello world, counter is 1, name is master
    

    总结

    spring不支持 直接在一个xml文件中定义两个相同id的bean,但是可以通过 import 的形式 在另外一个xml文件中定义相同 id 的bean。
    如果多个xml中定义相同 的 bean id ,Spring 默认会以最后加载到的bean为准,进行加载。


  • 相关阅读:
    css相关
    文章管理列表
    高性能MySQL基础篇
    mysql
    node.js开发实战
    React Hooks
    client-*,scroll-*,offset-*的区别
    将create-react-app从javascript迁移到typescript
    为Github项目添加Travis持续集成服务
    cookie储存
  • 原文地址:https://www.cnblogs.com/leihuazhe/p/9680664.html
Copyright © 2011-2022 走看看