2017-10-31 7 views
-1

한다고 가정 나는 다음과 같은 서비스 인터페이스 정의 (뿐만 아니라 구현) :몇 가지를 지정 (전부는 아니지만) 런타임에 생성자 매개 변수

interface Service1 { /* Methods omitted for brevity */ } 
interface Service2 { /* Methods omitted for brevity */ } 
나는 또한 수정할 수 없습니다이 인터페이스를 가지고

은 (는 밖으로의 내 손) :

interface YouAreNotAllowedToModifyMe { 
    Object createSomething(); 
} 

또한 나는 YouAreNotAllowedToModifyMe 인터페이스를 구현하고 현재 HttpServletRequest와 함께 이러한 서비스의 구현을 허용하는 클래스가 있다고 가정합니다. 요청은 구현 세부 사항이며 인터페이스의 일부가 아닙니다. 는 현재 HttpServletRequest 필요하기 때문에

class Demo implements YouAreNotAllowedToModifyMe { 

    private final HttpServletRequest request; 
    private final Service1 service1; 
    private final Service2 service2; 

    @Inject 
    public Demo(HttpServletRequest request, Service1 service1, Service2 service2) { 
    this.request = request; 
    this.service1 = service1; 
    this.service2 = service2; 
    } 

    public Object createSomething() { 
    // Use the request, service1, and service2 in order to create the object. 
    } 
} 

Demo는 그러나 나는 다른 매개 변수를 주입 돌봐 CDI 주입하고 싶습니다, 런타임 때까지 인스턴스화 할 수 없습니다. 어떻게해야합니까? 이것이 가능하기

기본적으로, 나는 (그렇지 않은) 좋아하는 것 : 당신은 절반 인수 주입 반 손에 의해 제공으로 생성자를 사용할 수 없습니다

class Foo { 

    @Inject 
    private final Instance<Demo> demoInstance; 

    public void doSomething(HttpServletRequest request) { 

    // This is pretend. This won't really work, though I wish it would. 
    // Essentially, I pass in the request and CDI takes care of everything else. 
    Demo demo = demoInstance.get(request); 
    } 
} 
+0

는 요청은 일회성 개체이며, 일반적으로보다 방법 매개 변수를 더 자연스럽게 일치 개체 필드. – chrylis

+0

@chrylis 전적으로 동의합니다. 그러나 간결하게하기 위해 코드를 단순화했습니다. 현실에서는'Demo' 클래스 (실제 이름이 아닌)가 인터페이스를 구현하여 자유롭게 변경할 수 없습니다. 해당 인터페이스의 메소드가 요청을 승인하지 않습니다. 그것은 내 구현의 세부 사항입니다. – battmanz

+0

상황을 더 잘 보여주기 위해 질문을 업데이트했습니다. – battmanz

답변

1

. 그러나 대안이 있습니다 :

  • HttpServletRequest에 대한 제작자를 생성하십시오. 더 나은 방법은 Delta Spike입니다. 그럼 실제로 HttpServletRequest을 삽입 할 수 있습니다!
  • 수정 Demo 오히려 그것을 구현하는 것보다, YouAreNotAllowedToModifyMe의 인스턴스에 대한 공장이 될 :

    @ApplicationScoped //probably-but not necessarily??? 
    public class Demo { 
        @Inject 
        private final Service1 service1; 
        @Inject 
        private final Service2 service2; 
    
        public YouAreNotAllowedToModifyMe makeYouAreNotAllowedToModifyMe(HttpServletRequest request) { 
         return new YouAreNotAllowedToModifyMeImpl(request); 
        } 
    
        private class YouAreNotAllowedToModifyMeImpl implements YouAreNotAllowedToModifyMe { 
         YouAreNotAllowedToModifyMeImpl(HttpServletRequest request) { 
          // do what you must... 
         } 
    
         // implement it! 
         // remember, you can actually use service1 & 
         // service 2 from the enclosing instance 
        } 
    } 
    
+0

정답을 보내 주셔서 감사합니다. 그로 인해 나는 작동하지 않을 길을 계속 지을 수 없었습니다. Angular.js를 사용하여 지난 2.5 년 동안 풀 타임 JavaScript 개발자로 일한 후에 Java로 돌아갈 것입니다. Angular.js에서는 실제로 지역 주민을 사용하여 절반과 절반을 할 수 있습니다. https://docs.angularjs.org/api/auto/service/$injector#instantiate를 참조하십시오. 방금 CDI에서도 그렇게 할 수 있다고 가정했습니다. – battmanz