无状态EJB使用EJB Schedule保持状态

时间:2012-10-29 18:46:44

标签: java jboss7.x cdi ejb-3.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

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

5 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

无状态bean可以根据需要多次使用。它们不是每次都必须创建的。您可以在http://docs.oracle.com/javaee/6/tutorial/doc/giplj.html

查看EJB LifeCycle

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

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