2012-10-04 2 views
1

나는 Seam을 처음 접했을 때 의존성 삽입물에 약간의 문제가 있습니다. 잘못된 방식으로 뭔가를하고있을 수도 있습니다!내 컨트롤러에서 새 스레드에 @In (jboss seam 사용)의 종속성을 주입 할 수없는 이유는 무엇입니까?

컨트롤러에서 해고 된 새 스레드에 종속성을 주입해야합니다. 예외는 없지만 간단히 null이됩니다. 먼저 스레드 내에서 d1 (아래 참조)을 재사용하려고했지만 그때는 null이었습니다.이 아이디어를 가지고이 객체에 다시 주석을 달았습니다 @In ... 불행히도 같은 일이 발생했습니다.

@Scope(ScopeType.CONVERSATION) 
@Name("myController") 
public class MyController{ 
    @In(create = true) 
    private Dependency1 d1; //ok, gets injected with no problems! 

    public void importantMethod(){ 
     //this part of the method is important and is fast 
     //but below comes an expensive part that takes some minutes 

     new Thread(new Runnable(){ 
      @In(create = true) 
      private Dependency1 anotherD1; //I still need d1 here!!!  

      @Override 
      public void run(){ 
       //I want to run expensive code here. 
       //A new thread is required in order to leave 
       //the visitor free to go else where on the web site 

       //First trial was to make d1 final and simply use it here! 
       //d1.doExpensiveStuff(); 
      }; 
     }).start(); 
    } 
} 

왜 이런 일이 일어나는 지 아는 사람이 있습니까? DI/Seam/Threading으로 작업 할 때 좋은 연습이 있습니까?

답변

5

주입 만 발생 : 심 구성 요소에서

  1. 는 (귀하의 예제에서, MyController이 구성 요소입니다, 당신은 내부 만들 익명 Runnable는 구성 요소가 아닙니다).
  2. Seam 수명주기 내부. 라이프 사이클은 JSF 요청, 비동기 실행 또는 수동으로 시작됩니다.

따라서 구성 요소가 아니기 때문에 @In은 스레드를 사용할 수 없으므로 Seam은 호출을 가로 채지 않습니다. 비동기 스레드 내에서 구성 요소를 잡아, 당신은 당신이 필요로하는 구성 요소를 라이프 사이클을 시작 솔기 API를 사용하여 얻을 필요가 :

@Scope(ScopeType.CONVERSATION) 
@Name("myController") 
public class MyController { 

    @In(create = true) 
    private transient Dependency1 d1; 

    public void importantMethod() { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       LifeCycle.beginCall(); // Start the Seam lifecycle 
       Dependency1 d1 = (Dependency1) Component.getInstance("dependency1"); 
       d1.doExpensiveStuff(); 
       LifeCycle.endCall(); // Dispose the lifecycle 
      } 
     }).start(); 
    } 
} 

Seam이 당신이 원하는 것을 바로 수행하는 @Asynchronous 주석을 제공합니다. 이 주석이 Seam 컴포넌트의 메소드에서 사용되면 메소드는 백그라운드 스레드 (Seam 소유의 스레드 풀에서 가져옴)에서 실행됩니다.

:

@Name("myBackgroundWork") 
public class MyBackgroundWork { 
    @In private transient Dependency1 d1; 

    @Asynchronous 
    public void runInBackground() { 
     d1.doExpensiveStuff(); 
    } 
} 

그런 MyController 당신이 배경 작업을 시작하고 즉시 반환됩니다 비동기 메서드를 호출 할 수 있습니다 : 정상적인 심 전화 인 것처럼 비동기 방법은 주입 종속성을 사용하실 수 있습니다 여기

@Scope(ScopeType.CONVERSATION) 
@Name("myController") 
public class MyController { 
    @In(create = true) 
    private MyBackgroundWork myBackgroundWork; 

    public void importantMethod() { 
     // Execution will return immediately and thread will start 
     myBackgroundWork.runInBackground(); 
    } 
} 

상세 정보 :

http://docs.jboss.org/seam/2.2.2.Final/reference/en-US/html/jms.html#d0e21609