我有几个这样的服务:
@Singleton
public SimpleService {
...
}
我有Managed Bean @ViewScoped,它应该创建一些复杂的对象。这些对象应该执行业务逻辑。我需要将这些服务传递给这个对象。
Managed Bean示例:
@ManagedBean
@ViewScoped
public class ExampleBean {
@Inject
private SimpleService simpleService;
...
public void customLogic() {
// in this method I should create complex object which should have services and some data.
// current implementation
ComplexObject object = new ComplexObject(SimpleService simpleService, ...)
}
}
通过@Inject批注将服务注入Managed Bean。为了创建这些对象 - 我正在使用构造函数并将这些服务作为参数传递。问题是:我可以在构造函数中传递服务吗?
答案 0 :(得分:3)
你可以:
private MyService myService; @Inject public void setMyService(MyService ms) { this.myService = ms; }
@Inject private MyService myService;
List<StorageAccount> accounts = azure.storageAccounts().list();
for (StorageAccount sa : accounts) {
System.out.println("Storage Account " + sa.name() + " created @ " + sa.creationTime());
}
获取引用(不推荐,高级用例除外):... MyService myService = CDI.current().select(MyService.class).get(); ...
CDI
获取引用(不推荐,高级用例或CDI 1.0除外):... BeanManager beanManager = CDI.getBeanManager(); // you can fetch a BeanManager reference by several other methods, I use CDI for simplicity here MyService myService = beanManager.getReference(MyService.class); ...
BeanManager
注释是@Singleton
而不是javax.ejb.Singleton
,那么您的bean实际上是一个EJB,您还可以使用任何允许您访问EJB的机制,例如{{ 1}}注释,或通过JNDI上下文。我个人倾向于通过方法注入,因为我发现它在大多数时候是最灵活的选择。在我看来,它也是对其他框架最“可移植”的(例如:Spring)
请记住,当您使用javax.inject.Singleton
或@Resource
方法获取CDI.current()
bean时,您有责任手动销毁获取的bean已完成,所以你不会落入this CDI-related memory leak。使用BeanManager
时,就像保存@Dependent
引用并在之后调用它一样简单:
CDI.current()
Instance
方法太低级,只能在CDI 1.0环境中使用(当...
Instance<MyService> msInstance = CDI.current().select(MyService.class);
MyService myService = msInstance.get();
...
msInstance.destroy(myService);
...
类尚不存在时)。您可以阅读链接的StackOverflow问题以获取更多详细信息。
答案 1 :(得分:2)
你在做什么都很好。您正在使用ManagedBean作为桥接来注入服务,然后将注入的变量传递给需要服务的ComplexObject。
应该考虑的唯一限制是,ComplexObject类本身可以是ManagedBean吗?这样你可以直接在它上面注入所有内容,但如果不可能,你可以使用bean。
我更喜欢提到的按字段注入选项,因为我认为它更具可读性。