Context and Dependency Injection @Disposes and @Produces
In this example we will use Context and Dependency injection annotations @Produces
and @Disposes
. We can create an injectable java.sql.Connection
using the @Produces
annotation. Remember that the container manages the initialisation and destruction of all the injectable beans. This means that we’ll have to inform the container which method it must call when it decides destruct the injectable bean. We can use the @Disposes
annotation.
Creating a JDBCConnectionProducer with @Produces and @Disposes
The createConnection
method producers a java.sql.Connection
. Which results in an injectable bean of type java.sql.Connection
. This requires explicit destruction. A disposer method allows the application to perform the customized cleanup of an object returned by a producer method. This example shows a utility class that creates and closes a JDBC connection. The createConnection takes a Derby JDBC driver, creates a connection with a specific URL, deals with the exceptions, and returns an opened JDBC connection. This method is annotated with @Produces. On the other hand, the closeConnection method terminates the JDBC connection. It is annotated with @Disposes.
java.sql.Connection
. The disposer method is automatically called when the client context or scoped object ends.package com.memorynotfound.cdi;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBCConnectionProducer {
@Produces
private Connection createConnection() throws SQLException {
String dbUrl = "jdbc:derby:memorynotfound/disposes;create=true";
return DriverManager.getConnection(dbUrl);
}
private void closeConnection(@Disposes Connection conn) throws SQLException {
conn.close();
}
}
Injecting the Connection using @Inject
Now lets inject the java.sql.Connection
into our service.
package com.memorynotfound.cdi;
import javax.faces.bean.ApplicationScoped;
import javax.inject.Inject;
import java.sql.Connection;
import java.sql.SQLException;
@ApplicationScoped
public class DerbyPingService {
@Inject
private Connection conn;
public void ping() throws SQLException {
conn.createStatement().executeQuery("SELECT 1 FROM SYSIBM.SYSDUMMY1");
}
}
Injecting the DerbyPingService
Next we create a simple CourseServlet
to trigger the service to see if all the injection points have been satisfied. Nothing fancy happening here. This is just a really easy way to test the application.
package com.memorynotfound.cdi;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
@WebServlet(urlPatterns = {"/courses"})
public class CourseServlet extends HttpServlet {
@Inject
private DerbyPingService pingService;
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<h1>Java EE: Context Dependency Injection @Inject annotation</h1>");
try {
pingService.ping();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Enabling CDI with beans.xml
Remember to include the beans.xml file into the META-INFO
or WEB-INF
folder of your application.
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bean-discovery-mode="all"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd">
</beans>