Attilio
Attilio

Reputation: 1722

Force Spring to use bean from the same configuration class

Description

Consider the case when there are two (or more) Spring configuration classes, each returning a bean with the same name (e.g. baseBean). Also, suppose that these config classes create other beans (e.g. anotherBean1 and anotherBean2), which contain baseBean instances.

Is there a way to make Spring inject the baseBean instances created in the same configuration class?

Example

// Beans
public abstract class BaseBean {
    public abstract String getName();
}

public class Bean1 extends BaseBean {
    @Override
    public String getName() {
        return "Bean1";
    }
}

public class Bean2 extends BaseBean {
    @Override
    public String getName() {
        return "Bean2";
    }
}

// Configurations
@Configuration
public class Config1 {

    @Bean
    public BaseBean baseBean() {
        return new Bean1();
    }

    @Bean
    public AnotherBean anotherBean1() {
        return new AnotherBean(baseBean());
    }

}

@Configuration
public class Config2 {

    @Bean
    public BaseBean baseBean() {
        return new Bean2();
    }

    @Bean
    public AnotherBean anotherBean2() {
        return new AnotherBean(baseBean());
    }
}

// Main class
public class Main {

    public static void main(String [] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config1.class, Config2.class);

        AnotherBean anotherBean1 = (AnotherBean) applicationContext.getBean("anotherBean1");
        AnotherBean anotherBean2 = (AnotherBean) applicationContext.getBean("anotherBean2");

        System.out.println(anotherBean1.baseBean.getName());
        System.out.println(anotherBean2.baseBean.getName());
    }
}

Expected output:

Bean1
Bean2

Actual output:

Bean2
Bean2

In other words, both Config1.anotherBean1() and Config2.anotherBean2() invoke Config2.baseBean(). Instead, I would like each Config class to invoke its own baseBean method, i.e. Config1.anotherBean1() should use Config1.baseBean() (and Config2.anotherBean2() should of course use Config2.baseBean()).

Is there a built-in way to force this behaviour somehow, e.g with some annotation?

Remarks

public class BaseConfig {
       @Bean
       public abstract BaseBean baseBean();

       @Bean
       public AnotherBean anotherBean() {
              return new AnotherBean(baseBean());
       }
}

          +----------------------------+
          |   BaseConfig               |
          |                            | 
          | + (abstract) baseBean()    |
          | + anotherBean()            |
          |____________________________|
                    /\
                   /__\
           _________|__________
   _______|_______      _______|__________
  |    Config1    |     |    Config2     |
  | + baseBean()  |     |  + baseBean()  |
  |_______________|     |________________|

Upvotes: 1

Views: 1184

Answers (1)

Ben M
Ben M

Reputation: 1892

Is there a reason that the different baseBean need to be Spring-Managed Beans themselves?

It sounds like you're only planning on using them from within AnotherBean so you could simply remove the @Bean annotation from ConfigX.baseBean() and you'd get the expected results.

Upvotes: 2

Related Questions