Java EE Session Beans – Java EE会话Bean

最后修改: 2017年 6月 10日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

Enterprise Session Beans can be broadly classified into:

企业会话Bean可大致分为:。

  1. Stateless Session Beans
  2. Stateful Session Beans

In this quick article, we are going to discuss these two main types of session beans.

在这篇文章中,我们将讨论这两种主要类型的会话Bean。

2. Setup

2.设置

To use Enterprise Beans 3.2, make sure to add the latest version to the dependencies section of the pom.xml file:

要使用Enterprise Beans 3.2请确保将最新版本添加到pom.xml文件的dependencies部分。

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
</dependency>
The latest dependency can be found in the Maven Repository. This dependency ensures that all Java EE 7 APIs are available during compile time. The provided scope ensures that once deployed; the dependency will be provided by the container where it has been deployed.

3. Stateless Beans

3.无状态的Bean

A stateless session bean is a type of enterprise bean which is commonly used to do independent operations. It does not have any associated client state, but it may preserve its instance state.

无状态会话Bean是企业Bean的一种类型,通常用于进行独立操作。它没有任何相关的客户端状态,但它可以保留其实例状态。

Let’s have a look at an example to demonstrate how a stateless bean works.

让我们来看看一个例子,以证明无状态Bean是如何工作的。

3.1. Creating the Stateless Bean

3.1.创建无状态 Bean

First, let’s create the StatelessEJB bean. We use the @Stateless annotation to mark the bean as stateless:

首先,让我们创建StatelessEJB bean。我们使用@Stateless注解来标记Bean为无状态。

@Stateless
public class StatelessEJB {

    public String name;

}

Then we create the first client of the above stateless bean, called EJBClient1:

然后我们创建上述无状态Bean的第一个客户端,称为EJBClient1

public class EJBClient1 {

    @EJB
    public StatelessEJB statelessEJB;

}

We then declare another client, named EJBClient2, that accesses the same stateless bean:

然后我们声明另一个客户端,名为EJBClient2,,访问同一个无状态Bean。

public class EJBClient2 {

    @EJB
    public StatelessEJB statelessEJB;

}

3.2. Testing the Stateless Bean

3.2.测试无状态 Bean</span

To test the statelessness of the EJB, we can use the two clients we declared above in the following way:

为了测试EJB的无状态性,我们可以用下面的方式来使用我们上面声明的两个客户端。

@RunWith(Arquillian.class)
public class StatelessEJBTest {

    @Inject
    private EJBClient1 ejbClient1;

    @Inject
    private EJBClient2 ejbClient2;

    @Test
    public void givenOneStatelessBean_whenStateIsSetInOneBean
      _secondBeanShouldHaveSameState() {

        ejbClient1.statelessEJB.name = "Client 1";
        assertEquals("Client 1", ejbClient1.statelessEJB.name);
        assertEquals("Client 1", ejbClient2.statelessEJB.name);
    }

    @Test
    public void givenOneStatelessBean_whenStateIsSetInBothBeans
      _secondBeanShouldHaveSecondBeanState() {

        ejbClient1.statelessEJB.name = "Client 1";
        ejbClient2.statelessEJB.name = "Client 2";
        assertEquals("Client 2", ejbClient2.statelessEJB.name);
    }

    // Arquillian setup code removed for brevity

}

We start by injecting the two EBJ clients into the unit test.

我们首先将两个EBJ客户端注入单元测试中。

Then, in the first test method, we set the name variable in the EJB that was injected into EJBClient1 to the value Client 1. Now, when we compare the value of the name variable in both clients, we should see that the value is equal. This shows that state is not preserved in stateless beans.

然后,在第一个测试方法中,我们将注入EJBClient1的EJB中的name变量设置为Client 1的值。现在,当我们比较两个客户端中的name变量的值时,我们应该看到值是相等的。这表明状态在无状态Bean中没有被保存下来

Let’s demonstrate that this is true in a different way. In the second test method, we see that once we set the name variable in the second client it ‘overwrites’ whatever value was given to it via ejbClient1.

让我们以不同的方式来证明这是真的。在第二个测试方法中,我们看到一旦我们在第二个客户端设置了name变量,它就会 “覆盖 “通过ejbClient1给予它的任何值。

4. Stateful Beans

4.有状态的Bean

Stateful session beans maintain state both within and between transactions. That is why each stateful session bean is associated with a specific client. Containers can save and retrieve the state of a bean automatically while managing instance pools of stateful session beans.

有状态的会话Bean在事务内部和事务之间都保持状态。这就是为什么每个有状态的会话Bean都与一个特定的客户端相关联。容器可以在管理有状态会话Bean的实例池时自动保存和检索Bean的状态。

4.1. Creating the Stateful Bean

4.1.创建有状态的 Bean

A stateful session bean is marked with the @Stateful annotation. The code for the stateful bean is as follows:

一个有状态的会话Bean是用@Stateful注解来标记的。有状态Bean的代码如下。

@Stateful
public class StatefulEJB {

    public String name;

}

The first local client for our stateful bean is written as follows:

我们的有状态Bean的第一个本地客户端被写成如下。

public class EJBClient1 {

    @EJB
    public StatefulEJB statefulEJB;

}

A second client called EJBClient2 is also created just like the EJBClient1:

第二个客户名为EJBClient2,也像EJBClient1一样被创建。

public class EJBClient2 {

    @EJB
    public StatefulEJB statefulEJB;

}

4.2. Testing the Stateful Bean

4.2.测试有状态的 Bean</span

The functionality of the stateful bean is tested in the EJBStatefulBeanTest unit test in the following way:

EJBStatefulBeanTest单元测试中,有状态Bean的功能以如下方式进行测试。

@RunWith(Arquillian.class)
public class StatefulEJBTest {

    @Inject
    private EJBClient1 ejbClient1;

    @Inject
    private EJBClient2 ejbClient2;

    @Test
    public void givenOneStatefulBean_whenTwoClientsSetValueOnBean
      _thenClientStateIsMaintained() {

        ejbClient1.statefulEJB.name = "Client 1";
        ejbClient2.statefulEJB.name = "Client 2";
        assertNotEquals(ejbClient1.statefulEJB.name, ejbClient2.statefulEJB.name);
        assertEquals("Client 1", ejbClient1.statefulEJB.name);
        assertEquals("Client 2", ejbClient2.statefulEJB.name);
    }

    // Arquillian setup code removed for brevity

}

As before the two EJB clients are injected into the unit test. In the test method, we can see that the value of the name variable is set via the ejbClient1 client and is maintained even though the value of name set via the ejbClient2 is different. This demonstrates that the state of the EJB is maintained.

如前所述,两个EJB客户端被注入到单元测试中。在测试方法中,我们可以看到name变量的值是通过ejbClient1客户端设置的,即使通过ejbClient2设置的name的值是不同的,也会被保持。这表明EJB的状态得到了维护

5. Stateless vs. Stateful Session Bean

5.无状态与有状态会话Bean

Now let’s have a look at the major difference between the two types of session beans.

现在让我们来看看这两种会话Bean的主要区别。

5.1. Stateless Beans

5.1.无状态Bean

  • Stateless session beans maintain no state with the client. For this reason, they can be used to create a pool of objects which interact with multiple clients
  • Since stateless beans don’t have any state per client, they are better performance wise
  • They can handle multiple requests from multiple clients in parallel and
  • Can be used for retrieving objects from databases

5.2. Stateful Beans

5.2.有状态的Bean</span

  • Stateful session beans can maintain state with multiple clients, and the task is not shared among clients
  • The state lasts for the duration of the session. After the session is destroyed, the state is not retained
  • The container can serialize and store the state as a stale state for future use. This is done to save application server resources and to support bean failures and is passivation
  • Can be used to solve producer-consumer type problems

6. Conclusion

6.结论

So we have created two types of session beans and corresponding clients to invoke the methods from the beans. The project demonstrates the behavior of the two main types of session beans.

因此,我们已经创建了两种类型的会话Bean和相应的客户端来调用Bean的方法。该项目演示了两种主要类型的会话Bean的行为。

As always, the source code for the article is available on GitHub.

一如既往,本文的source代码可以在GitHub上找到。