In this article we will look at EJB - Enterprise JavaBeans. This technology is part of the Java EE specification. We will touch on issues such as:
- what is EJB;
- what is the history of EJB;
- what types of EJB are there?
A Brief History of EJB
Back in 1996, when the author of this article was 5 years old, Java was already popular among developers. The reason for this was the friendly API, automatic garbage collection, etc. Java was widely used in systems responsible for the backend. However, despite all the delights of the language, programmers of that time needed certain functionality that was not yet implemented in the JDK. These needs were:- ensuring data persistence;
- transaction integrity
- competitive access to data (multi-threading control);
- and most likely something else.
What is EJB
EJB in a sense is a collective term that, depending on the context, can mean either the Enterprise JavaBeans technology itself in general, or some specific Enterprise JavaBean software component (bean) that is part of the EJB technology. The definition of EJB as a technology is given on Wikipedia: Enterprise JavaBeans (also often used as an abbreviation EJB) is a specification of a technology for writing and supporting server components containing business logic. It is part of Java EE. This technology is typically used when business logic requires at least one of the following services, and often all of them:- support for data persistence: data should be safe even after stopping the program. Most often achieved using a database;
- support for distributed transactions;
- support for parallel data modification and multithreading;
- event support;
- naming and directory support (JNDI);
- security and restriction of access to data;
- support for automated installation on the application server;
- remote access.
EJB types
Let's summarize. An EJB is a regular Java class marked with one of the special annotations. Such classes are called beans. Depending on what annotation the class is marked with, it will be a representative of one or another type of EJB (beans). There are three main types of beans:- Message Driven Beans (message driven beans);
- Entity Beans - defined in the JPA (Java Persistence API) specification and used to store data;
- Session Beans.
- stateless (without state);
- stateful (with support for the current session state);
- singleton (one object for the entire application; starting from EJB 3.1).
Session Beans
Session Beans, or session beans, are a specific type of bean. They encapsulate business logic that the client can programmatically invoke by calling the bean's methods. A method call can do:- locally, by another class in the same JVM as the session bean;
- remotely, over the network, from another JVM, using Java RMI (Remote Method Invocation) technology.
@Stateless
. Let's give an example below:
import javax.ejb.Stateless;
@Stateless
public class StatelessEjbExample {
public String sayHi() {
return "Hi, I'm Stateless EJB!";
}
}
Session beans that support the current session state (Stateful) retain information about their state between calls to it from the same client and terminate their existence upon an explicit request from the client. This is achieved due to the fact that stateful beans are unique for each client. An example of a task for which this type of bean can be responsible is keeping the shopping cart in an online store up to date for each user. The life cycle of these beans is managed by the EJB container. These beans are also destroyed when the client exits. Such beans are also quite easy to create. This is a Java class marked with the annotation Stateful
. Example below:
import javax.ejb.Stateful;
@Stateful
public class StatefulEjbExample {
public String sayHi() {
return "Hi, I,m Stateful EJB";
}
}
Singleton session beans are initiated once during the lifetime of the application and exist for the entire life of the application. Such beans are designed for situations in which one state must be shared among all clients. Like stateless beans, in standalone beans the developer needs to ensure that the environment inside the bean is organized in a thread-safe manner. Let's give an example of a Singleton bean, which is as easy to create as its counterparts, which were discussed above. It's easy to guess that this is a Java class with the annotation @Singleton
. However, in this case you need to be careful. There are two annotations, identical in syntax, but different in purpose and located in different packages:
- javax.ejb.Singleton
- javax.inject.Singleton
javax.ejb
. Example below:
import javax.ejb.Singleton;
@Singleton
public class SingletonEjbExample {
public String sayHi() {
return "Hi, I'm Singleton EJB!";
}
}
Message Driven Beans
Message Driven Beans, or MDBs, or message-driven beans, implement some business logic, like session beans. But unlike its relatives, MDB has one important difference. Clients never call MDB methods directly. Such beans most often act as listeners for JMS (Java Message Service) messages and serve to organize asynchronous message exchange between parts of the system. An example of such a message would be a request for delivery of inventory from an automated retail system to a supply management system. Below is an example of an MDB bean. Unlike session beans, its creation is a little more interesting:import javax.annotation.Resource;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
@MessageDriven(mappedName = "jms/TestQueue")
public class MessageDrivenEjbExample implements MessageListener {
@Resource
private MessageDrivenContext messageDrivenContext;
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
TextMessage msg = (TextMessage) message;
msg.getText();
}
} catch (JMSException e) {
messageDrivenContext.setRollbackOnly();
}
}
}
The annotation MessageDriven
makes our MDB class a bean. Inside the annotation, using JNDI (read about JNDI here ), the name of the JMS distribution is determined, to which our class becomes a listener. In addition, our class implements the interface MessageListener
and its method onMessage
. This method will be called when some message arrives from the queue/distribution with the name defined inside the annotation MessageDriven
.
Entity beans
Part of the EJB technology is the JPA specification. JPA, or Java Persistence API, is a specification that provides Object-Relational Mapping (ORM) of Java objects (Entity beans) and provides an API for storing, retrieving, and managing such objects. JPA allows you to represent data from a database as Java objects, as well as save Java objects as records in the database. Not every class can act as such an object, but Entity beans. Entity Bean is a Java class that represents a table in a database. Display (mapping) is achieved through the use of special annotations. With their help, a Java class is compared with a table in the database, as well as the fields of a Java class are compared with the fields of a database table. Here's an example of an Entity bean, with comments in the code:@Entity // Делает данный класс Entity бином
@Table(name = "employee") // "Связывает" данный класс с таблицей employee в БД
public class Employee implements Serializable {
@Id // Говорит о том, что поле ниже является первичным ключом
@GeneratedValue(strategy = GenerationType.AUTO) // Определяет тип генерации значений первичного ключа
private int id;
@Column(name="name") // "Связывает" поле ниже с полем name в таблице employee в БД
private String name;
@Column (name="age") // "Связывает" поле ниже с полем age в таблице employee в БД
private int age;
// getters and setters...
}
It is worth noting that this type of bean makes sense to study only in the context of studying the JPA specification.
Writing an application: EJB HelloWorld
In this section, we will write a small Java EE HelloWorld application, which we will deploy on the GlassFish server. Before reading this article, it is highly recommended that you read the article on setting up your local environment .-
Create a new Maven project in IntelliJ IDEA.
File -> New -> Project...
-
Click Next .
-
Fill in the Maven project parameters:
-
Click Finish
-
The project has been created and has the following structure:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.javarush.lectures</groupId>
<artifactId>ejb_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
</project>
Next, you can move on to the Java code. Our application will be the simplest. We will have 1 servlet and 1 EJB. This will be a stateless session bean. Inside the EJB we will define only 1 method that will return the string “Hello World”. First of all, let's create a package com.javarush.lectures
. Then, inside the package com.javarush.lectures
, we will create our bean - DemoEJB. The bean code is given below:
import javax.ejb.Stateless;
@Stateless
public class DemoEJB {
public String helloWorld() {
return "Hello world!";
}
}
As said earlier, everything is quite simple. Our next step is to create a servlet that will pass the value from the EJB as a response to the HTTP request. It's worth noting that servlets are not the topic of this article, but you will still need to use them to demonstrate EJB. To do this, let's create a new servlet DemoServlet
in the same package as the EJB. Its code is below:
@WebServlet("/helloWorld")
public class DemoServlet extends HttpServlet {
@EJB
private DemoEJB ejb;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write(ejb.helloWorld());
}
}
Here are some short comments on the code. Abstract @WebServlet("/helloWorld")
- defines our class as a servlet that will process HTTP requests to the endpoint /helloWorld
. Our class has one field - DemoEJB ejb
. This is our bean defined earlier. An annotation over a class field— @EJB
performs dependency injection (DI). Those. The ejb variable is automatically initialized with a new instance when required. Our class is a descendant of HttpServlet and overrides one of the superclass methods - doGet
. This method processes HTTP GET requests and takes two parameters - HttpServletRequest
and HttpServletResponse
. HttpServletRequest
serves to obtain information about an incoming HTTP request. HttpServletResponse
needed to generate a response to a request. Inside the method, we get the object PrintWriter
from the response object ( HttpServletResponse
), using the getWriter()
. Next, we can write some value to the resulting object using the write
. Which, in fact, is what we use by writing into the PrintWriter
-a object the value obtained from the EJB we defined (the value is the string “Hello World!”). The client that sent the HTTP request will receive this value as a response to its request. The next step is to launch the application on the GlassFish Java EE server. To do this, we will create a new configuration, as described in the article on setting up the local environment . Below is a screenshot of the finished configuration for the current project. Make sure that you have the GlassFish server installed before starting: After creating the launch configuration, launch the application using the Run -> Run 'ejb_demo' menu or using the Shift+F10 hotkey . After launch, you can see its logs: And also the browser that opens: All this indicates that the application works as intended.
Conclusion
In this article we got acquainted with EJB - Enterprise JavaBeans. We considered questions such as:- What is EJB?
- EJB History
- Different types of EJBs
- Message Driven Beans (message driven beans);
- Entity Beans - defined in the JPA (Java Persistence API) entities specification and used to store data;
- Session Beans:
- stateless (without state)
- stateful (with support for the current session state)
- singleton (one object for the entire application; starting from EJB 3.1)
GO TO FULL VERSION