在 Batchlet 的 @ApplicationScoped bean 中注入自定义 CDI 范围

Injection of custom CDI scope in @ApplicationScoped bean of Batchlet

我在 Batchlet(批次 API)的 @ApplicationScoped bean 中注入用我自己的 @JobScoped CDI Scope 注释的 bean 时遇到问题。

我已经定义了 @JobScoped 注释:

@Documented
@Scope
@Target({ TYPE, METHOD, FIELD })
@Retention(RUNTIME)
public @interface JobScoped
{
}

我已经通过 CDI 扩展注册了我的自定义 JobScopeContext

public class JobScopeExtension implements Extension
{
   public void registerJobScopeContext(@Observes final AfterBeanDiscovery p_event, final BeanManager p_beanManager)
   {
      p_event.addContext(new JobScopeContext(p_beanManager));
   }
}

JobScopeContext,实施 Context API 的 get 方法来管理我的 @JobScoped bean 的创建。

public class JobScopeContext implements Context {

    /**
     * {@inheritDoc}
     * 
     * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual)
     */
    @Override
    public <T> T get(final Contextual<T> p_contextual) {
        // do stuff
    }

    /**
     * {@inheritDoc}
     * 
     * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual,
     *      javax.enterprise.context.spi.CreationalContext)
     */
    @Override
    public <T> T get(final Contextual<T> p_contextual, final CreationalContext<T> p_creationalContext) {
        // do stuff
    }
}

我不会在这里谈论我管理 @JobScoped bean 生命周期的方式,因为这对我的问题来说无关紧要。

我现在定义了我的 @JobScoped bean :

@JobScoped
public class MyBeanJobScopedImpl implements MyBeanJobScoped {

    @Override
    public String getId() {
        return "MyString";
    }

}

还有一个 @ApplicationScoped bean,它具有前一个 bean 作为依赖项:

@ApplicationScoped
public class MyBeanApplicationScoped {

    @Inject
    private MyBeanJobScoped m_beanJobScoped;

    public String callBeanJobScoped()
    {
        return m_beanJobScoped.getId();
    }

}

这是我现在观察到的行为:

在 JAX-RS 资源中使用

如果我将 MyBeanApplicationScoped bean 注入到 JAX-RS 资源中:

@Path("custom")
public class RessourceREST {

    @Inject
    private MyBeanApplicationScoped m_beanApplicationScoped;

    @GET
    @Path("testApplicationScoped")
    public String test() {
        return m_beanApplicationScoped.callBeanJobScoped();
    }
}

然后每次调用m_beanApplicationScoped.callBeanJobScoped()方法时,都会调用我JobScopeContextclass的Context#get(Contextual)Context#get(Contextual, CreationalContext)方法来解析注入的bean .这是正常行为。

在 Batchlet 中使用(未按预期工作)

现在,如果我将 MyBeanApplicationScoped bean 注入到 Batchlet 中:

@Named("MyBatchlet")
@Dependent
public class MyBatchlet extends AbstractBatchlet{

    @Inject
    private MyBeanApplicationScoped m_beanApplicationScoped;

    @Override
    public String process() throws Exception {
        // TODO Auto-generated method stub

        m_beanApplicationScoped.callBeanJobScoped();
        return "OK";
    }


}

第一次调用 Batchlet(启动拥有此 Batchlet 的作业)时,我的 JobScopeContext class 的 Context#get(Contextual)Context#get(Contextual, CreationalContext) 方法被调用解决注入的bean。

但是如果我再次调用作业,Contextget 方法就不会再被调用。就好像 @JobScoped bean 作为 @ApplicationScoped bean 注入到 @ApplicationScoped bean 中。

我是不是遗漏了什么或者我的实现有什么问题?

谢谢。

我解决了用 @NormalScope.

替换 JobScoped 范围的 @Scope 注释的问题