1

我在 EJB Stateless 上使用 JBoss AS 7 和 Schedule 方法。我的问题是即使 EJB 也是无状态的,它保持其状态,这给我带来了麻烦。这是示例:

计时器:

@Stateless
public class TestTimer {

    @Inject HelloWorldService helloWorld;

    @SuppressWarnings("unused")
    @Schedule(second="*/10", minute="*", hour="*", info="MyTimer")
    private void execute() {
        System.out.println(helloWorld.sayHello());
        System.out.println(this.toString() + " "+ helloWorld.toString());
    }
}

注入的 HelloWorldService:

public class HelloWorldService {

    public String sayHello() {
        return "Hello World!";
    }
}

我原以为System.out.println(this.toString() + " "+ helloWorld.toString());每次计时器运行时该行都会打印一次不同的时间,因为TestTimer每次都会是一个新实例,但我错了:

16:43:50,003 INFO  [stdout] (EJB default - 3) foo.service.TestTimer@4a56936f foo.service.HelloWorldService@79e98289
16:44:40,022 INFO  [stdout] (EJB default - 1) foo.service.TestTimer@4a56936f foo.service.HelloWorldService@79e98289

我做错了什么,这是预期的行为,还是什么?

4

5 回答 5

2

EJB 规范没有声明无状态 bean在每次调用后丢弃它们的状态。它指出应用程序开发人员不能依赖 bean来保持其状态。有一个微妙但非常重要的区别。同一个bean实例可能会被多次使用;这并不能否定无状态。

于 2012-10-29T18:51:19.197 回答
2

重要的是每个计时器都有一个查找,您可能会获得 bean 的不同实例
,但“可能”意味着您仍然可能获得相同的实例,因为它是从
容器为您管理的 bean 池中获得的。
使用相同的计时器对象没有任何问题,
只要它提供适当的功能即可。
这意味着,作为开发人员,您不能对 bean 的状态做出任何假设,无论它是否会在重新查找 bean 时恢复。

于 2012-10-29T18:53:03.377 回答
1

无状态 bean 可以根据需要多次使用。它们不是每次都被创造出来的。您可以在http://docs.oracle.com/javaee/6/tutorial/doc/giplj.html查看 EJB LifeCycle

于 2012-10-29T18:51:28.533 回答
1

这是预期的行为(根据 Java EE 规范),实际上比这要复杂一些。

应用服务器正在管理一个过期会话 bean 池,并使用该池中的实例来处理客户端请求。如果服务器上有一些负载,那么将从池中使用几个 bean,每个 bean 都有自己的状态。因此,在您的测试中,您有时会打印相同的字符串值,有时会打印另一个字符串值。

您不应将属性用于业务逻辑。但是,出于技术目的使用属性(例如,保留对数据库的引用)有时是一个好主意。

于 2012-10-29T18:52:27.833 回答
1

容器有一个无状态会话 bean 池。它在容器内部处理活动实例的数量(据我所知)对于您的情况,计时器似乎调用了相同的实例。

于 2012-10-29T18:52:29.423 回答