【问题标题】:Java EE 7 Batch API : produce job scoped CDI BeanJava EE 7 Batch API:生成作业范围的 CDI Bean
【发布时间】:2017-01-15 12:41:09
【问题描述】:

我目前正在开发一个 Java EE 7 Batch API 应用程序,我希望我的一个 CDI Bean 的生命周期与当前工作相关。 实际上我希望这个 bean 有一个 @JobScoped 范围(但它在 API 中不存在)。我也希望这个 bean 可以在我的任何作业类中注入。

起初,我想创建自己的 @JobScoped 范围,使用 JobScopedContext 等。但后来我想到 Batch API 有 JobContext bean,每个 bean 都有唯一的作业 ID。

所以我想知道我是否可以使用这个JobContext 来管理我的作业范围 bean 的生命周期。

例如,我希望我的 bean 成为工作范围:

@Alternative
public class JobScopedBean
{
   private String m_value;

   public String getValue()
   {
      return m_value;
   }

   public void setValue(String p_value)
   {
      m_value = p_value;
   }
}

然后我将拥有此 bean 的生产者,它将返回与当前作业关联的 JobScopedBean(感谢 JobContext,每个作业都是唯一的)

public class ProducerJobScopedBean
{

  @Inject
  private JobContext m_jobContext;// this is the JobContext of Batch API

  @Inject
  private JobScopedManager m_manager;

  @Produces
  public JobScopedBean getObjectJobScoped() throws Exception
  {
      if (null == m_jobContext)
     {
         throw new Exception("Job Context not active");
      }

      return m_manager.get(m_jobContext.getExecutionId());
   }
}

还有持有我JobScopedBean地图的经理:

@ApplicationScoped
public class JobScopedManager
{
   private final ConcurrentMap<Long, JobScopedBean> mapObjets = new   ConcurrentHashMap<Long, JobScopedBean>();

   public JobScopedBean get(final long jobId)
   {
      JobScopedBean returnObject = mapObjets.get(jobId);
      if (null == returnObject)
      {
         final JobScopedBean ajout = new JobScopedBean();
         returnObject = mapObjets.putIfAbsent(jobId, ajout);

         if (null == returnObject)
         {
            returnObject = ajout;
         }
      }
      return returnObject;
   }

当然,我会在每个作业结束时管理JobScopedBean 的销毁(通过JobListener 和CDI Event)。

如果我对这个解决方案有误,你能告诉我吗?

这对我来说看起来是正确的,但也许我错过了什么?

可能有更好的方法来处理这个问题?

谢谢。

【问题讨论】:

    标签: java cdi batch-processing java-ee-7


    【解决方案1】:

    因此,归结为创建基于作业的 @Dependent 范围 bean。对于寿命比作业短的 bean 可以正常工作,因此仅适用于标准范围 @Dependent(@Request/@Session/@Converstion 可能没问题,但不适用于此处)。

    会对其他 Scope 造成问题,尤其是@ApplicationScoped/@Singleton。如果您将 JobScopedBean 注入其中之一。当您第一次需要它们时,您可能(不)幸运地拥有一个活动的作业,但是 bean 将始终附加到该初始作业(@Dependent 范围 bean 不是伪作用域,因此不会创建代理来获取上下文实例)

    如果您想要类似的东西,请创建一个自定义范围。

    【讨论】:

    • 谢谢@k5_。这是我错过的重点,真丢人!当然问题出在@ApplicationScoped bean 上(实际上即使在@ApplicationScoped bean 中注入JobContext 也会解决问题,因为注入的bean 将依赖于@ApplicationScoped bean)。感谢您指出我的解决方案中的问题,我知道有问题但我无法弄清楚。
    • 我将尝试自定义 CDI 范围,这似乎是实现这一目标的唯一方法。
    猜你喜欢
    • 1970-01-01
    • 2015-07-29
    • 2012-01-20
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 2018-06-22
    相关资源
    最近更新 更多