为什么我不能从控制器内的新线程中注入带有@In的依赖项(使用 jboss seam)?



我在依赖注入方面遇到了一些麻烦,因为我对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时,是否有任何良好的实践?

仅发生注入:

  1. 在Seam组件中(在您的示例中,MyController是一个组件,您在其中创建的匿名Runnable不是组件)
  2. Seam生命周期内部。生命周期可以通过JSF请求、异步执行或手动启动

因此,您不能在线程中使用@In,因为它不是一个组件,Seam不会拦截对它的调用。要获得异步线程中的组件,您需要使用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拥有的线程池)中执行。请注意,异步方法将能够像使用普通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

最新更新