【问题标题】:Injecting different bean according to resource method called根据调用的资源方法注入不同的bean
【发布时间】:2016-01-11 12:06:00
【问题描述】:

我们在我们的应用程序中使用CDI(不是EJB)。我们有一个资源层、一个业务 bean 层和一个数据库处理程序 bean 层。所有这些豆子都是@RequestScoped。现在,资源注入了一个业务 bean,而后者又注入了它需要的所有 dbhandler bean。由于这是CDI,并且没有对象池(至少据我所知),有没有办法根据调用的方法决定注入(并因此创建)哪些bean?例如,我有 2 个业务 bean 方法。 Method1 使用DAOBean1,Method2 使用DAOBean1 AND DAOBean2。现在,即使我只想使用 Method1,业务 bean 也会注入两个 DAO bean。有没有办法根据方法调用过滤注入的bean?这很重要,因为我们有一个 bean,它在其 @PostConstruct 上创建数据源连接,但并非所有 bean 方法都查询数据库,这意味着我们在将 bean 用于非 db 相关方法时会创建冗余连接。

【问题讨论】:

  • 听起来更好的选择是注入连接池。
  • 一个简单的解决方法是不注入 DAOBean2,而是通过 CDI BeanManager 以编程方式查找它。然后您可以按需创建 bean。
  • 这些都是很好的解决方法,但我正在寻找所描述问题的解决方案。连接问题只是未经过滤的 bean 注入引起的问题之一。
  • 这些 bean 的范围是什么?
  • @RequestScope。使用其他范围(应用程序、会话)不会有问题,因为它们永远存在于活动会话中。我发现的唯一解决方案是使用某种 ProgrammaticLookup(通过Instance<MyBean> 注入或使用BeanManager),它工作正常,但现在我很好奇一个更优雅的解决方案。最后,我想描述每个函数需要什么 bean,并在函数调用之后但在函数执行之前动态注入它们。使用Interceptor 听起来像是一个解决方案,但我认为它无法实现。

标签: java dependency-injection cdi


【解决方案1】:

似乎没有办法根据调用的方法注入不同的bean。由于注入是在 bean 创建期间解决的,因此容器无法知道将调用哪个函数,并且在我们决定之前无法保持注入。为了解决这个问题,我们要么使用 Programmatic Bean Lookup(使用 BeanManager 类)来访问上下文 bean,要么我们可以通过 Instance<T> 接口访问它们。如果我们使用Instance 接口,我们必须小心不要出现内存泄漏。这是为什么?因为以这种方式注入的每个 bean 都会获得@Dependent 的范围,这意味着当注入器类本身被销毁时,它将被释放。例如,如果注入器类的范围是@ApplicationScoped,则 bean 本身将永远不会被释放,从而造成内存泄漏。在这种情况下,我们使用 Instance 接口的方法,称为 `destroy(myBean)。

例子:

@ApplicationScoped
public class MyClass {

  @Inject
  Instance<MyBean> myBeanInstance;

  public void myMethod() {
    //...
    MyBean bean = myBeanInstance.get();
    // Do stuff with bean
    myBeanInstance.destroy(bean); //Release the bean otherwise it will hold memory
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-23
    • 2019-09-21
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多