title: Bean with multiple constructors in Java-based Spring configuration
body: <p>I am trying to refactor some application to use Spring DI instead of plain java and stuck with the issue.</p>
  
  <p>Basically i have a class with several constructors:</p>
  
  <pre><code>  public MyClass() {
      this(new A());
    }
  
    public MyClass(A a) {
      this(a, new B()));
    }
  
    public MyClass(String string) {
      this(new A(string));
    }
  
    public MyClass(A a, B b) {
      this.a = a;
      this.c = a.getC();
      this.b = b;
      this.d = b.getD();
    }
  
    public MyClass(A a, B b, D d) {
      this.a = a;
      this.c = a.getC();
      this.b = b;
      this.d = d;
    }
  </code></pre>
  
  <p>These constructors are used in many places, some of them in code, some of them in tests, etc.</p>
  
  <p>Now, i am introducing spring java-based application config:</p>
  
  <pre><code>@Configuration
  public class ApplicationConfiguration {
  
    @Bean
    MyClass myClass() {
      return null;
    }
  
  }
  </code></pre>
  
  <p>And trying to rewrite all the places with getting a bean from application context:</p>
  
  <pre><code>AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
  MyClass myClass = (MyClass) context.getBean("myClass", arg1, arg2);
  </code></pre>
  
  <p>And the problem is that in some places i have only arg1, in some both arg1 and arg2, in some i have no args. So, how could i express that in application configuration?</p>
  
  <p>Also the bean is singletone, so if i, for example create several beans with different arguments then this requirement will be broken, i.e.</p>
  
  <pre><code>@Configuration
  public class ApplicationConfiguration {
  
    @Bean
    MyClass myClass1() {
      return new MyClass();
    }
  
    @Bean
    MyClass myClass2(A a) {
      return new MyClass(a);
    }
  
    //etc
  }
  </code></pre>
  
  <p>is definitely not a solution.</p>
  
  <p>Thanks in advance</p>
  
  <p><strong>Upd.</strong>
  Looks like the +Avi answer is the right one, but i still don't understand how to do things right.</p>
  
  <p>I created a junit4 test:</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(classes = ApplicationConfiguration.class)
  public class MyTest {
  
      @Autowired
      private ApplicationContext applicationContext;
  
      @Before
      public void setupMyClass() {
      //    myClass = new MyClass();
          myClass = (MyClass) applicationContext.getBean("myClass");
      }
  }
  </code></pre>
  
  <p>So, here i want to use MyClass in test, so there is no Foo-like bean like in Avi answer. </p>
  
  <p>I modified context for "different scenarios, and in each of them you need to construct MyClass with different arguments - you need to create multiple beans, that each instantiate its own MyClass" (i got the phrase in a wrong way, but here is what i came to):</p>
  
  <pre><code>@Configuration
  public class ApplicationConfiguration {
  
    //Note: beans have the same name
  
    @Bean
    MyClass myClass() {
      return new MyClass();
    }
  
    @Bean
    MyClass myClass(A a) {
      return new MyClass(a);
    }
  
    //etc
  }
  </code></pre>
  
  <p>But now there is another issue: applicationContext.getBean("myClass") returns me random(depending of number of beans with same name and parameters) bean and not a bean without parameters. And when i specify args - applicationContext.getBean("myClass", new Object[]{}); it says me that it is allowed only for prototype scoped beans. But i want a singleton bean.</p>
  
  <p>Looks like i need another advice: how to get rid of several beans with same names in configuration? Maybe i need a clever factory, or maybe @Autowired(required=false) can help here?</p>
  
  <p>Even if i had Foo-like object in my test, how should i use it in test?</p>
  
  <pre><code>@Configuration
  @Import(ApplicationConfiguration.class)
  public class FooConfiguration {
       @Autowire
       MyClass myClass; //but which one constructor?
  
       @Bean
       Foo foo() {
           return new Foo(myClass);
       }
  
  }
  </code></pre>
  
  <p>I don't want to create MyClass in each configuration itself, i want to have only one, which i can import...</p>
  
  <p><strong>Upd2.</strong></p>
  
  <p>Okay, i removed all constructors and leaved only one, which have all parameters</p>
  
  <pre><code>@Configuration
  public class ApplicationConfiguration {       
  
      @Bean
      MyClass myClass(A a, B b, C c, D d) {
        return new MyClass(a, b, c, d);
      }
  }
  </code></pre>
  
  <p>Now in test i do:</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(classes = MyTest.TestConfiguration.class)
  public class MyTest {
  
    @Configuration
    @Import(ApplicationConfiguration.class)
    static class TestConfiguration {
  
      @Bean
      A a() {
          return new A();
      }
  
      @Bean
      B b() {
          return new B();
      }
  
      @Bean
      C c() {
          return b().getC();
      }
  
      @Bean
      D d() {
          return c().getD();
      }
    }
  
    @Autowired
    private MyClass myClass;
  }
  </code></pre>
  
  <p>But now, i don't understand how to avoid writing this for every and every test..</p>