Multiple singletons can be useful when it becomes necessary or desirable to represent multiple objects in an application that need to be shared across the application. In this recipe, we will expand upon the previous recipe's SingletonExample
application by adding a GameBean
.
The second singleton is called GameBean
and maintains the state of the game. It is assumed that player information maintained in the PlayerBean
and this EJB, and its supporting files, need to be created before the GameBean
is created. The GameBean
will use the player files or initialized database to support the game.
Adding multiple singleton session beans to an application generally requires:
The @DependsOn annotation is added to the dependent bean. That is the bean that is to be created last.
In this recipe, we will reuse the SingletonExample
application. Start by adding a second singleton to the packt
package called GameBean
as listed below. We will follow this with modifications to the application's servlet.
@Singleton @Startup @DependsOn("PlayerBean") public class GameBean { private String state; @PostConstruct private void initialize() { // Use player files/database to initialize the state of the game playerState = "Initilizing"; System.out.println("GameBean initialized"); } public String getState() { return state; } public void setState(String state) { this.state = state; } }
Modify the GameServlet
to use the GameBean
and retrieve the state of the player.
public class GameServlet extends HttpServlet { @EJB private GameBean game; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println("<html>"); out.println("<head>"); out.println("<title>Servlet GameServlet</title>"); out.println("</head>"); out.println("<body>"); out.println("<h3>State: " + game.getState() + "</h3>"); out.println("</body>"); out.println("</html>"); } finally { out.close(); } } ... }
Execute the servlet using the URL shown in the following screenshot:
The GameBean
used the @Singleton annotation to designate the bean as a singleton. The @Startup annotation was used to force the creation of the bean as soon as the application started. The @DependsOn annotation specified that the PlayerBean
must be created first.
The GameServlet
wass simple. DI is used to inject a GameBean
and then it used the getState
method to retrieve its state.
More than one singleton bean can be used in the @DependsOn annotation with their names separated by commas. However, the actual order of construction of the dependent beans is indeterminate. If the order of singleton creation is important, then multiple @DependsOn annotations are needed.
For example, if we introduce a third singleton called, EnemyBean
, we may want to force the PlayerBean
and the EnemyBean
to be created before the creation of the GameBean
. This is done in the @DependsOn annotation by listing the two dependent beans separated by a comma.
@DependsOn("PlayerBean, EnemyBean") public class GameBean {
This declaration will force the creation of the PlayerBean
and the EnemyBean
first but it does not specify the order in which these two EJBS will be created. When it is desirable to create the PlayerBean
first followed by the EnemyBean
, and then finally the GameBean
, the @DependsOn annotation will need to be used with both the GameBean
and EnemyBean
singletons.
@DependsOn("EnemyBean") public class GameBean {...} @DependsOn("PlayerBean ") public class EnemyBean {...} public class PlayerBean {...}
3.147.27.171