2017-09-11 7 views
1

저는 JavaEE와 의존성 주입의 개념을 처음 접했습니다. 그러나 나는 그것이 사용할 수있는 모든 방법을 모른다 할지라도 그것을 공정하게 이해하고있다.인터페이스, 외부 라이브러리 클래스를 JavaEE 애플리케이션에 삽입하는 방법은 무엇입니까?

@Local 
public interface MyInterfaceLocal { 
    SomeType getMeSometype(); 
} 

이 인터페이스가 상태 EJB입니다 구현하는 클래스 :

나는 다음과 같이 로컬 인터페이스를 가지고있다.

@Stateless 
public class MyInterfaceImpl { 
    public SomeType getMeSomeType() { 
     //Some implementation details... 
     ExternalLibraryClass externalLib = new ExternalLibrary(arg1, arg2); 
     return externalLib.externalLibMethod(); 
    } 
} 

이제 문제는 내가 externalLib의 인스턴스를 피할 수 있으며, 이것이 어떻게든지해서 주입하자 어떻게, 무엇입니까? 예를 들어, 이것이 내가 인터페이스로 생성 한 다른 EJB라면, EJB 컨테이너가 아래와 같이 @EJB 주석을 사용하여 인스턴스화를 처리하도록 할 수 있습니다.

@Stateless 
public class MyInterfaceImpl { 
    @EJB 
    AnotherInterface anotherInterfaceImpl; 

    public SomeOtherType getMeSomeType() { 
     //Some implementation details... 

     return anotherInterfaceImpl.someMethod(); 
    } 
} 

나는 (같은)을 할 수 있기를 원하는 날 수 있습니다 내가 있기 때문에 사용하고 외부 라이브러리,이 : 현재 사용하고있는 기본 외부 라이브러리

  1. 변경 내 코드 기반을 최소한으로 변경하십시오. 필요한 경우 더 나은 것으로 바뀔 수 있습니다.
  2. MyInterfaceImpl 클래스를 단위 테스트하고 싶을 때 쉽게 모의 삽입하기.

지금까지 그 매개 변수 ExternalLibrary이며 따라서 수동 방법 파라미터 주입 일종의 수행 래퍼 생성 방법 AT-

  1. 를 보았다. 그래도 내 구현은 기본 라이브러리에 밀접하게 결합됩니다. (아니면 내가 제대로하지 않겠다.)

  2. Context & Dependency Injection 컨테이너를 사용하여 주입 (EJB 컨테이너와 같은 방법)을 사용한다. Producers을 사용하는 방법에 대해 조사했습니다. 내가 Producers에 관해 CDI와 관련하여 어떤 일을하는지 이해하지만, 나는 이것을 어떻게 활용할 수 있는지에 대해 머리를 감쌀 수 없다. 아니면 내가 올바른 길을 가고있다해도?

는 UPDATE : 나는 나를 CDI 생산자 더 잘 이해 도움이 몇 가지 기사를 발견하고 그 접근 방식에 의해 진행하려고했지만 또 다른 문제에 직면했다. 그래서 지금 내가 가진 :

public class ExternalLibraryProducer { 
    @Produces 
    private ExternalLibraryClass1 extrnalLibraryClassProducer() { 
     return new ExternalLibraryClass1("SomeString", 7); 
     //The constructor actually takes a string and another commplex type 
     //as parameters. I am keeping it a little simple here. 
     //I am trying to set the ExternalLibraryClass1() arguments 
     //programmatically at runtime. 
    } 
} 

가 지금은 생산 할 개체의 생성자는 매개 변수를 취

ExternalLibraryProducer.java, 문자열 및 정수라고 할 수 있습니다. 나는 내가 원하는 객체를 생성하기 위해이 파라미터들을 전달하기 위해 Qualifier을 생성 할 수 있다고 생각했다.

ExternalLibraryClass1Qualifier.java

@Qualifier 
@Retention(RUNTIME) 
@Target({METHOD}) 
public @interface ExternalLibraryClass1Qualifier { 
    String argument1(); 
    Int argyment2(); //This is actually another complex type. Keeping it 
    //simple here. 
} 

지금 무엇을 내가 원하는, 내가 (속성 파일에서 가정) 인수 값은 런타임에 프로그래밍 방식으로 설정할 수 싶어요.그리고 나는 이것을하는 방법을 이해할 수 없습니다. 그래서 마지막 주사는 아래처럼 보일 것입니다.

@Stateless 
public class MyInterfaceImpl { 
    @Inject 
    @ExternalLibraryClass1Qualifier(argument1 = "something", argument2 = 7) 
    ExternalLibrary externalLib; 

    public SomeType getMeSomeType() { 
     //Some implementation details... 
     return externalLib.externalLibMethod(); 
    } 
} 

어떤 안내해 주셔서 감사합니다.

+0

CDI 제작자는 한정자 인수가 여기에 속임수를 쓰지는 않지만 좋은 접근 방식처럼 보입니다. 주입 지점이 일치하지 않습니다. 내가 생각하는 생산자 방법. 어프로치를 뒤집고, 객체를 생성하는 동안 제작자가 볼 수있는 곳에 'argument1'과'argument2'가 저장되어 있을까요? – Siliarus

답변

0

CDI 생산자 여기에 갈 수있는 방법입니다, 유일한 문제는, 정확히 어떻게 당신이 그들을 구축하고 싶어한다.

당신은 논쟁이 속성 파일에서 왔다고 말했기 때문에 나는 접근법을 뒤집어서 프로듀서 메쏘드가 그 프로퍼티 파일을 체크하고 값을 추출하도록 권한다.) : 당신은 분명 어떤 규정이 필요하지 않으며 단순히 @Inject ExternalLibraryClass1을 할 수있는이와

@Produces 
private ExternalLibraryClass1 produceExternalLibraryInstance() { 
    // read the properties from the file or from any cache you use 
    String arg1 = PropertyReader.getarg1(); 
    Integer arg2 = PropertyReader.getArg2(); 
    // create object with those args 
    return new ExternalLibraryClass1(arg1, arg2); 
} 

.

ExternalLibraryClass1을 삽입하는 객체를 만들 때 생성자를 기반으로 호출된다는 점에 유의하십시오. 곧 속성 파일에서 args를 가져올 수 있습니다. (생산품을 읽을 때 문제가 발생하지 않아야합니다. 일부 캐시가 있으면 더 까다로울 수 있습니다)

0

ExternalLibrary에 대한 생성자 방법을 사용하면 개체 생성에 필요한 인수를 사용할 수 있으며이 인수는 CDI 작성자를 통해 생성 할 수 있습니다.

public class ExternalLibraryProducer { 

    private String name; 

    private int age; 

    public ExternalLibraryProducer() { 
     // set name and age from properties file or elsewhere 
     // or you can set them individually on their respective producer methods, but might be costly considering you need to read the properties file twice 
    } 

    @Produces 
    public String name() { 
     return name; 
    } 

    @Produces 
    public int age() { 
     return age; 
    } 

    .... 

    @Produces 
    private ExternalLibraryClass1 extrnalLibraryClassProducer(String name, int age) { 
     // Or you can use them directly here, if you opt to not separate this config from the dependencies 
     return new ExternalLibraryClass1(argument, age); 
    } 
}