我正在使用jboss AS 7和EJB无状态的计划方法。我的问题是,即使是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
我做错了什么,这是预期的行为,还是什么?
重要的是每个计时器都有查找,您可能会得到bean的不同实例
,但是"可能"意味着您可能仍然获得相同的实例,因为它是从豆类池中获得的
该容器为您管理。
使用同一计时器对象没有错,
只要提供适当的功能。
这意味着,作为开发人员,您无法对豆的状态做出任何假设,并且在豆的新查找时是否会恢复它。
EJB规范在每次调用后没有说明无状态bean dovers 。它指出,应用程序开发人员不得依靠bean 保持其状态。有一个微妙但非常重要的区别。可以多次使用相同的bean实例;这不会消除无状态。
可以根据需要多次使用无状态豆。他们不是每次都会创建必要的。您可以在http://docs.oracle.com/javaee/6/tutorial/doc/giplj.html
这是预期的行为(每个Java EE规格),实际上比这更复杂。
App Server正在管理一池bean bean,并使用该池中的实例来管理服务器客户端请求。如果您在服务器上有一些负载,那么将从池中使用几种豆,每个豆子都有其自己的状态。因此,在您的测试中,您有时会打印相同的字符串值,有时会打印另一个字符串值。
您不应将属性用于业务逻辑。但是,将属性用于技术目的(例如,对DB的参考)有时是一个好主意。
容器中有一个无状态会话bean。容器内部处理活动的数量(据我所知)(据我所知)对于您的情况,似乎由计时器调用相同的实例。