Java EE 7 批处理 API:生成作业范围的 CDI Bean

Java EE 7 Batch API : produce job scoped CDI Bean

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

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

所以我想知道我是否可以用这个 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 的生产者return 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)。

你能告诉我这个解决方案是否有误吗?

我觉得是正确的,但也许我遗漏了什么?

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

谢谢。

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

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

如果您想要这样的东西,请创建自定义范围。