假设我定义了以下服务接口(以及实现):
interface Service1 { /* Methods omitted for brevity */ }
interface Service2 { /* Methods omitted for brevity */ }
我也有这个无法修改的界面(它不在我的手中):
interface YouAreNotAllowedToModifyMe {
Object createSomething();
}
进一步假设我有一个实现YouAreNotAllowedToModifyMe
接口的类,并接受这些服务的实现以及当前的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
直到运行时才能实例化,因为它需要当前的HttpServletRequest
,但是我希望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 :(得分:1)
你不能使用注入了一半参数的构造函数和一半手工提供的构造函数。但是你有其他选择:
HttpServletRequest
创建一个制作人。更好的是,使用Delta Spike。那么你实际上可以注入 HttpServletRequest
!将Demo
修改为YouAreNotAllowedToModifyMe
的实例 factory ,而不是实现它:
@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
}
}