【Spring注解开发】setAllowBeanDefinitionOverriding---同名bean覆盖的问题

源码:https://github.com/nieandsun/spring-study

1.前置知识

所谓的Spring容器,其实就是一个大Map,其管理的bean的id(也就是bean的name)应该都是不一样的,假如项目中有两个bean的name一样了,在项目启动时一般会报类似于下图的同名异常.
在这里插入图片描述

  • 但在有些情况下,spring并不会报"同名异常" ,其处理方式是:
如果两个bean的name相同,则后出现的bean会覆盖前面出现的同名bean
  • 所带来的问题:
如果启动时,对于同名的bean加载没有异常信息,出现问题后将会很难进行定位。
  • 产生原因:
spring中的DefaultListableBeanFactory类有个属性:allowBeanDefinitionOverriding,
默认情况下为true,即允许重名的bean可以被覆盖。

2 .Demo演示

2.1 demo结构介绍

【Spring注解开发】setAllowBeanDefinitionOverriding---同名bean覆盖的问题_第1张图片

2.2 源码

  • Test04Repository
@Repository
public class Test04Repository {
    private String  flag = "1";
    public String getFlag() {
        return flag;
    }
    public void setFlag(String flag) {
        this.flag = flag;
    }

    @Override
    public String toString() {
        return "Test04Repository{" +
                "flag='" + flag + '\'' +
                '}';
    }
}
  • Test04Service
@Service
public class Test04Service {
    @Resource
    private Test04Repository test04Repository;
    public void whichRepository() {
        System.err.println("test04Repository====>" + test04Repository);
    }
}
  • 配置类
@Configuration
@ComponentScan("com.nrsc.springstudy.C04_setAllowBeanDefinitionOverriding.test01")
public class C04DemoConfig01 {
    @Bean
    public Test04Repository test04Repository() {
        Test04Repository test04Repository = new Test04Repository();
        test04Repository.setFlag("2");
        return test04Repository;
    }
}
  • 启动类
  /**
     * 不使用setAllowBeanDefinitionOverriding,发现spring容器中test04Repository只有一个
     */
    @Test
    public void test01() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(C04DemoConfig01.class);
        Test04Service test04Service = ac.getBean(Test04Service.class);
        test04Service.whichRepository();
        String[] names = ac.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
    /**
     * 使用setAllowBeanDefinitionOverriding=true,发现spring容器中test04Repository还是只有一个
     */
    @Test
    public void test02() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        ac.setAllowBeanDefinitionOverriding(true);
        ac.register(C04DemoConfig01.class);
        ac.refresh();

        Test04Service test04Service = ac.getBean(Test04Service.class);
        test04Service.whichRepository();
        String[] names = ac.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
    /**
     * 使用setAllowBeanDefinitionOverriding=false,发现会报There is already ... 异常
     */
    @Test
    public void test03() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
        ac.setAllowBeanDefinitionOverriding(false);
        ac.register(C04DemoConfig01.class);
        ac.refresh();

        Test04Service test04Service = ac.getBean(Test04Service.class);
        test04Service.whichRepository();
        String[] names = ac.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }

3.展示一下结果

  • setAllowBeanDefinitionOverriding=true或不设置此属性时

【Spring注解开发】setAllowBeanDefinitionOverriding---同名bean覆盖的问题_第2张图片

  • setAllowBeanDefinitionOverriding=false时

【Spring注解开发】setAllowBeanDefinitionOverriding---同名bean覆盖的问题_第3张图片

你可能感兴趣的:(Spring)