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 不是伪范围的,因此不会创建代理来获取上下文实例)
如果您想要这样的东西,请创建自定义范围。
我目前正在开发 Java EE 7 Batch API 应用程序,我希望我的一个 CDI Bean 的生命周期与当前工作相关。
实际上我希望这个 bean 有一个 @JobScoped
范围(但它不存在于 API 中)。我也希望这个 bean 可以注入到我的任何工作中 class.
起初,我想创建自己的 @JobScoped
范围,带有 JobScopedContext
等。但后来我想到 Batch API 有 JobContext
每个 bean 具有唯一作业 ID 的 bean。
所以我想知道我是否可以用这个 JobContext
.
例如,我希望我的 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 不是伪范围的,因此不会创建代理来获取上下文实例)
如果您想要这样的东西,请创建自定义范围。