Java 使用EJB调度保持状态的无状态EJB

Java 使用EJB调度保持状态的无状态EJB,java,jboss7.x,cdi,ejb-3.1,Java,Jboss7.x,Cdi,Ejb 3.1,我在EJB无状态上使用JBoss AS 7和一个调度方法。我的问题是,即使EJB是无状态的,它也保持其状态,这给我带来了麻烦。以下是一个例子: 计时器: @Stateless public class TestTimer { @Inject HelloWorldService helloWorld; @SuppressWarnings("unused") @Schedule(second="*/10", minute="*", hour="*", info="MyTi

我在EJB无状态上使用JBoss AS 7和一个调度方法。我的问题是,即使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

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

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

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

无状态bean可以根据需要多次使用。它们不是每次都必须创建的。您可以在

中查看EJB生命周期,无状态bean可以根据需要多次使用。它们不是每次都必须创建的。您可以在

上查看EJB生命周期,这是预期的行为(根据JavaEE规范),实际上比这要复杂一些

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


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

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

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


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

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

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

重要的是,每个计时器都有一个查找,您可能会得到不同的bean实例
, 但是“may”表示您仍然可以获得相同的实例,因为它是从bean池中获得的
容器为您管理的
使用相同的计时器对象没有任何问题,
只要它提供适当的功能

这意味着,作为一名开发人员,您不能对bean的状态做出任何假设,在对bean进行新的查找时,将恢复bean的状态

重要的是,每个计时器都有一个查找,您可能会得到一个不同的bean实例
, 但是“may”表示您仍然可以获得相同的实例,因为它是从bean池中获得的
容器为您管理的
使用相同的计时器对象没有任何问题,
只要它提供适当的功能

这意味着,作为一名开发人员,您不能对bean的状态做出任何假设,在对bean进行新的查找时,将恢复bean的状态

所有这些都是很好的答案,帮助我了解了一些我的问题。我会接受你的,因为它更适合我描述这个案件。所有这些都是很好的答案,帮助我了解了一些我的问题。我会接受你的,因为它更适合我描述案件事实上它需要它。事实上,任何一个州都必须被认为是“虚假的”,因为缺乏契约(根据规范,容器可能会根据需要汇集无状态bean)。@him我不确定在我发布这个答案后的六年里发生了什么变化。EJB容器现在是否需要在每次方法调用后显式地丢弃无状态bean的状态?不需要丢弃它,但不保证维护它。请记住,对于SLSB,“this”指向代理,而不是具体的实现。例如,如果您有SLAB a和b(同一EJB类型的池中的两个实例),那么从a.method1()到a.method2()的调用可能会被回答为“b”,因为容器可以自由地优化其调用,不管它认为合适与否。您无法保证是谁应答该调用,只是它是池中该类型的实例(在轻负载下可能只包含1个实例)。事实上,它需要它。事实上,任何一个州都必须被认为是“虚假的”,因为缺乏契约(根据规范,容器可能会根据需要汇集无状态bean)。@him我不确定在我发布这个答案后的六年里发生了什么变化。EJB容器现在是否需要在每次方法调用后显式地丢弃无状态bean的状态?不需要丢弃它,但不保证维护它。记住,对于SLSB,“th