在同一请求中获取@RequestScoped CDI bean的不同实例

时间:2016-02-05 10:56:24

标签: java-ee ejb cdi

在WildFly 8/10上,我有一个简单的SLSB发射CDI事件:

@Stateless
@Remote(CDITestRemote.class)
@Local(CDITestLocal.class)
public class CDITestBean implements CDITestRemote, CDITestLocal {

    @Inject
    private Event<IVolumeEvent> events;

    @Override
    public String insert(final String value) {
        final IVolumeEvent event = new VolumeEvent();
        events.fire(event);

        return String.format("value: %s", value);
    }
}

@ApplicationScoped&#34; CDI事件观察员&#34;对于EJB触发的事件类型:

@ApplicationScoped
public class VolumeEventObserver {

    private Logger logger = LoggerFactory.getLogger(VolumeEventObserver.class);

    @Inject
    private TransactionHandler txHandler;

    public void inProgress(
            @Observes(during = TransactionPhase.IN_PROGRESS) final IVolumeEvent event) {
        logger.info("@Observes progress() {}", String.valueOf(txHandler));
    }

    public void afterSuccess(
            @Observes(during = TransactionPhase.AFTER_SUCCESS) final IVolumeEvent event) {
        logger.info("@Observes success() {}", String.valueOf(txHandler));
    }

    public void afterFailure(
            @Observes(during = TransactionPhase.AFTER_FAILURE) final IVolumeEvent event) {
        logger.info("@Observes failure() {}", String.valueOf(txHandler));
    }

}

TransactionHandler@RequestScoped CDI bean:

@RequestScoped
public class TransactionHandler {
    // some methods here...    
}

当我在注入REST资源的EJB实例上调用insert()时,我在TransactionHandler期间的VolumeEventObserver中的任何观察者方法中都看到11:23:58,476 INFO [VolumeEventObserver] (default task-11) @Observes progress() TransactionHandler@7687eead 11:23:58,479 INFO [VolumeEventObserver] (default task-11) @Observes success() TransactionHandler@7687eead 的相同实例。按预期请求到REST端点:

11:42:01,461 INFO  [VolumeEventObserver] (EJB default - 2) @Observes progress() TransactionHandler@2e65f10d
11:42:01,463 INFO  [VolumeEventObserver] (EJB default - 2) @Observes success() TransactionHandler@2a5a7019

但是当我进行远程EJB调用时,我会在同一个请求中看到不同的实例:

TransactionHandler

所以ContextNotActiveException似乎不是请求作用域。

JSR-299表示请求范围是活动的:

  

在任何EJB的任何远程方法调用期间   任何EJB [...]

的异步方法调用

由于没有/a[+-]{2}\s|\s[+-]{2}a/g; ,我认为请求范围是活跃的 - 所以为什么我会得到不同的实例呢?

它是相同的线程(从日志条目中可以看到),并且事务也是相同的。

2 个答案:

答案 0 :(得分:0)

您看到的行为符合规范。规范说远程EJB调用期间请求上下文是活动的。它并没有说对同一个bean的重复调用只能在一个请求中运行。

答案 1 :(得分:0)

在黑暗中只是一枪:你试过用这个吗?

@ApplicationScoped
public class VolumeEventObserver {

    private Logger logger = LoggerFactory.getLogger(VolumeEventObserver.class);

    @Inject
    private Instance<TransactionHandler> txHandler;

    public void inProgress(
        @Observes(during = TransactionPhase.IN_PROGRESS) final IVolumeEvent event) {
        logger.info("@Observes progress() {}", String.valueOf(txHandler.get()));
    }

}

也许“实例”会做到这一点。