上下文和依赖注入(CDI)使您的对象能够自动为它们提供依赖项,而不是创建它们或将它们作为参数接收。CDI还为您管理这些依赖项的生命周期。
例如,考虑以下servlet:
1 @WebServlet("/cdiservlet") 2 public class NewServlet extends HttpServlet { 3 private Message message; 4 5 @Override 6 public void init() { 7 message = new MessageB(); 8 } 9 10 @Override 11 public void doGet(HttpServletRequest request, HttpServletResponse response) 12 throws IOException { 13 response.getWriter().write(message.get()); 14 } 15 }
这个servlet需要一个实现Message
接口的对象实例 :
1 public interface Message { 2 public String get(); 3 }
servlet创建自己的以下对象的实例:
1 public class MessageB implements Message { 2 public MessageB() { } 3 4 @Override 5 public String get() { 6 return "message B"; 7 } 8 }
使用CDI,这个servlet可以声明它对Message
实例的依赖性,并让它由CDI运行时自动注入。新的servlet代码如下:
1 @WebServlet("/cdiservlet") 2 public class NewServlet extends HttpServlet { 3 @Inject private Message message; 4 5 @Override 6 public void doGet(HttpServletRequest request, HttpServletResponse response) 7 throws IOException { 8 response.getWriter().write(message.get()); 9 } 10 }
CDI运行时查找实现Message
接口的MessageB
类,查找类,创建它的新实例,并在运行时将其注入servlet。要管理新实例的生命周期,CDI运行时需要知道实例的范围应该是什么。在此示例中,servlet仅需要实例来处理HTTP请求; 然后可以对实例进行垃圾回收。这是使用javax.enterprise.context.RequestScoped
注释指定的:
1 @RequestScoped 2 public class MessageB implements Message { ... }
对于此servlet的CDI详情请参见官方文档:https://javaee.github.io/tutorial/cdi-basic001.html