3

일반 Java 대신 Spring DI를 사용하도록 일부 응용 프로그램을 리팩터링하려고 시도하고 있습니다. 내가 지금 Java 기반 스프링 구성에서 다중 생성자가있는 Bean

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; 
    } 

이 생성자

가 많은 장소에서 사용되는 코드에서 그들 중 일부, 테스트에 그들 중 일부 등

: 기본적으로

나는 여러 생성자를 가진 클래스가 소개 스프링 자바 기반 응용 프로그램의 설정 :

@Configuration 
public class ApplicationConfiguration { 

    @Bean 
    MyClass myClass() { 
    return null; 
    } 

} 

그리고 애플리케이션 컨텍스트에서 빈을 받고 모든 장소를 다시 작성하려고 :

그리고 문제는 어떤 곳에서는 일부 arg1과 arg2가 있고 어떤 args도 없다는 것입니다. 그렇다면 어떻게 응용 프로그램 구성에서 표현할 수 있습니까? 내가 예를 들어 다음이 요구 사항은 파괴됩니다 다른 인수와 함께 여러 콩을 만들 그래서 만약

또한 빈 즉

@Configuration 
public class ApplicationConfiguration { 

    @Bean 
    MyClass myClass1() { 
    return new MyClass(); 
    } 

    @Bean 
    MyClass myClass2(A a) { 
    return new MyClass(a); 
    } 

    //etc 
} 

확실히 해결책이 아니다, singletone입니다. 사전

UPD에

감사합니다. + Avi 응답이 올바른 것 같지만 여전히 올바르게 작업하는 방법을 이해하지 못합니다.

@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"); 
    } 
} 

그래서, 여기에 내가 시험에 MyClass에 사용하려는, 그래서 푸 같은 콩은 아비의 대답처럼이 없습니다 :

은 내가 junit4 테스트를 만들었습니다.

"다른 시나리오에 대한 컨텍스트를 수정했으며 각기 다른 인수로 MyClass를 구성해야합니다. 여러 개의 빈을 만들어야하는데, 각 빈은 각각 고유 한 MyClass를 인스턴스화해야합니다"

@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 
} 

하지만 지금은 또 다른 문제가 있습니다 : 그러나 여기 내가)에 온 것입니다 applicationContext.getBean ("myClass가") 반환 나 임의 (동일한 이름과 매개 변수) 콩이 아닌 콩의 수에 따라 매개 변수가없는 bean. 그리고 args - applicationContext.getBean ("myClass", new Object [] {});을 지정할 때; 프로토 타입 범위 콩에서만 허용된다고 나에게 말한다. 하지만 싱글 톤 빈을 원해.

다른 조언이 필요한 것 같습니다. 구성에서 같은 이름의 여러 콩을 제거하는 방법은 무엇입니까? 어쩌면 영리한 공장이 필요하거나 어쩌면 @Autowired (필수 = false)가 여기에 도움이 될까요?

내 테스트에서 Foo와 유사한 객체가 있더라도 테스트에서 어떻게 사용해야합니까? 나는 각 구성 자체 MyClass의를 만들지 않으

@Configuration 
@Import(ApplicationConfiguration.class) 
public class FooConfiguration { 
    @Autowire 
    MyClass myClass; //but which one constructor? 

    @Bean 
    Foo foo() { 
     return new Foo(myClass); 
    } 

} 

, 난 가져올 수있는 단 하나의, ...

Upd2을 갖고 싶어.

좋아, 내가 모든 생성자를 제거하고 모든 매개 변수 테스트에서 지금

@Configuration 
public class ApplicationConfiguration {  

    @Bean 
    MyClass myClass(A a, B b, C c, D d) { 
     return new MyClass(a, b, c, d); 
    } 
} 

내가 할 수있는 단 하나, 잎이 달린 :

@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; 
} 

하지만 지금, 내가 방법을 이해하지를 매 시험마다 이것을 쓰는 것을 피하십시오.

답변

1

나는 당신이 뭔가를 놓치고 있다고 생각합니다. 의존성을 사용하는 클래스 내에서 의존성을 구성하는 것으로 이동하면이를 삽입하기 위해 의존성을 전혀 만들지 않아야합니다. 나는 그 조금 애매한 것 같아요, 제가 예와 함께 설명하자

class Foo { 
    public void someMethod() { 
     MyClass myClass1 = new MyClass(); 
     // do something with myClass1 
    } 
} 

그리고 지금 당신이 주입하려는 :

하는의 당신이 맥락에서 만드는 빈을 사용하는 클래스 Foo 있다고 가정 해 봅시다 콩. 귀하의 사례에서와 마찬가지로 AnnotationConfigApplicationContext으로 직접 전화하지 마십시오. 이 같은 일을하고 있습니다 : 응용 프로그램의 맥락에서

class Foo { 
    private MyClass myClass1; 

    public Foo(MyClass myClass1) { 
     this.myClass1 = myClass1; 
    } 

    public void someMethod() { 
     // do something with myClass1 
    } 
} 

당신이뿐만 아니라 콩으로 Foo을 만들 수 있습니다. 같은 뭔가 :

@Configuration 
public class ApplicationConfiguration { 

    @Bean 
    Foo createFooBean() { 
     return new Foo(createMyClassBean()); 
    } 

    @Bean 
    MyClass createMyClassBean() { 
     return new MyClass(); 
    } 

} 
  • 당신은 당신이 빈을 만들 때 @Configuration 클래스를 전달해야 MyClass의 생성자에 인자가있는 경우

    .
  • 시나리오가 다르며 각기 다른 인수를 사용하여 MyClass을 구성해야하는 경우 여러 개의 빈을 만들어야하며 각 빈은 각각 MyClass을 인스턴스화합니다.
+0

분명히 설명해 주셔서 감사합니다. 그것에 대해 생각해 봐야합니다 .. –

+0

내가 아직 이해할 수없는 것이 있습니다. 나는 질문을 업데이트했다. 일을 올바르게하는 방법을 보여 주시겠습니까? –

+0

@ VadimKirilchuk - 답변을 수락하면 모든 것을 이해할 수 있습니다. – Avi

관련 문제