我需要在Web应用程序中创建一个服务器套接字来监听Asterisk AGI请求,但是我需要在套接字中启用CDI注入,不知道该怎么做。
今天我已经有了这个套接字工作得很好,问题是我不能用套接字注入CDI bean。
例如:
class RequestProcessor implements Runnable
{
private Socket socket;
@Inject
private PhoneService phoneService;
@Override
public void run()
{
// Do the logic here
}
}
接收请求并发送到池的方法。
ExecutorService pool = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(25000);
Socket client = server.accept();
pool.execute(new RequestProcessor(client));
这不是生产代码,只是一个插图示例!
我无法使@Inject PhoneService phoneService正常工作。
答案 0 :(得分:2)
正如我们已经建立的那样,new
RequestProcessor
不会填充@Inject
- 注释字段,因为new
完全切断了DI系统。所以你需要一种方法来实现它。
您的目标看起来特别重要,因为RequestProcessor
需要DI提供的依赖项(phoneService
)和以编程方式提供(socket
)。作为一般规则,我建议不要在可能的情况下混合两者 - 一旦你使用DI,它就像病毒一样传播。让这发生。如果您可以设计您的系统,以便(几乎)为您注入所有内容,那就是风扇!
那就是说,你的情况完全可行。
看起来你在某些类中有一些方法,这是一个潜在的注射部位。假设这个未知类实际上是由CDI创建的,您可以@Inject
PhoneService
进入该类,然后将其传递给RequestProcessor
构造函数:
public class SomeClass {
@Inject
private PhoneService phoneService;
private void someMethod() {
ExecutorService pool = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(25000);
Socket client = server.accept();
pool.execute(new RequestProcessor(client, phoneService));
}
}
或者您可以使用工厂创建RequestProcessor
个实例,最终基本上会产生相同的效果。你可以手工编写这个工厂,看起来很熟悉:
public class RequestProcessorFactory {
@Inject
private PhoneService phoneService;
public RequestProcessor createNewProcessor(Socket socket) {
return new RequestProcessor(socket, phoneService);
}
}
然后将该工厂的实例注入您的班级:
public class SomeClass {
@Inject
private RequestProcessorFactory requestProcessorFactory;
private void someMethod() {
ExecutorService pool = Executors.newCachedThreadPool();
ServerSocket server = new ServerSocket(25000);
Socket client = server.accept();
pool.execute(requestProcessorFactory.createNewProcessor(client));
}
}
有第三种方法可以做到这一点,类似于Guice's assisted injection.如果你提供接口,它实际上只会为你生成工厂实现。据我所知,CDI不支持这一点,但有at least one CDI extension which does。
快乐的DIING!