【问题标题】:is it possible to create a bean using new() without making its inner beans unusable?是否可以使用 new() 创建一个 bean 而不会使其内部 bean 不可用?
【发布时间】:2020-06-05 06:11:39
【问题描述】:

我将 Weld 用于 CDI。 我正在寻找一种方法来运行包含注入 bean 的周期性线程。

主要我想创建:

executorService.scheduleWithFixedDelay(new ExampleThread(), 1, 1, TimeUnit.SECONDS);

ExampleThread 在哪里:

@ApplicationScoped
public class ExampleThread implements Runnable {

    @Inject
    private SomeBean someBean;


    public ExampleThread() {}

    @Override
    public void run() {
        someBean.do();
    }
}

问题是,一旦我使用 new() 创建了 ExampleThread,它就会使其内部 bean 无法使用。 有没有办法以可行的方式创建 ExampleThread?

【问题讨论】:

  • 答案提供了一些有效的指针——我的偏好是通过构造函数传递依赖项。但是您能否提供更多关于为什么您希望在每次计划执行时重新创建Runnable 的信息?我的印象是使用 @ApplicationScoped bean 本身的注入实例可能就足够了。

标签: java jakarta-ee cdi weld


【解决方案1】:

您可以改为通过其构造函数将 CDI bean 的引用传递给可运行对象。像这样的:

@ApplicationScoped
public class Foo
{
    @Inject
    private SomeBean someBean;

    // ...

    public void someMethod()
    {
        // ...
        executorService.scheduleWithFixedDelay(new ExampleThread(someBean), 1, 1, TimeUnit.SECONDS);
    }
}
public class ExampleThread implements Runnable
{
    private SomeBean someBean;

    public ExampleThread(SomeBean someBean)
    {
        this.someBean = someBean;
    }

    @Override
    public void run() {
        someBean.do();
    }
}

【讨论】:

    【解决方案2】:

    只需注入提供程序而不是使用新的:

    @Inject
    private Provider<ExampleThread> exampleThreadProvider;
    
    ...
    
    executorService.scheduleWithFixedDelay(exampleThreadProvider.get(), 1, 1, TimeUnit.SECONDS);
    

    【讨论】:

    • 这是一个比公认答案更清洁的解决方案,因为它只是在任何地方使用纯注入。
    【解决方案3】:

    你可以这样注入 bean:

    executorService.scheduleWithFixedDelay(new ExampleThread(), 1, 1, TimeUnit.SECONDS);
    

    并在 ExampleThread 中按以下方式初始化 bean:

    public class ExampleThread implements Runnable
    {
        private SomeBean someBean;
    
        public ExampleThread()
        {
            this.someBean = CDI.current().select(SomeBean.class).get();
        }
    
        @Override
        public void run() {
            someBean.do();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多