CDI(Weld)整合<1>整合JavaEE環境組件資源

除了基礎部分和高級部分,CDI的第三個主題是整合。

CDI還設計了經過SPI提供集成點到Java EE平臺的協同工做的平臺以外的技術[在Java EE 6發佈後,各類各樣的Java EE平臺擴展(構建在CDI擴展SPI之上)涌現了出來。]。這SPI CDI定位爲便攜式擴展和集成現有的框架和技術,做爲整合JavaEE生態系統的基礎。固然, Java EE平臺將永遠沒法規範世界中全部在Java應用程序開發使用的有趣的技術.
你可能不會永遠須要直接使用這些SPI ,但不要無視他們的存在。你可能會間接使用它們,好比你使用第三方擴展,如DeltaSpike 。

一:Java EE integration

CDI是徹底集成到Java EE環境的.

1. Built-in beans

在Java EE環境中,容器提供瞭如下內置Bean,所有用限定符 @Default :
  • 當前JTA的UserTransaction,
  • 標識當前調用者主要的identity(身份ID),
  • 默認Bean Validation的 ValidationFactory
  • 一個驗證器的默認ValidationFactory,
  • HttpServletRequest, HttpSession and ServletContext
注意:FacesContext 是沒法注入的.但可使用下面的Producer方法:
import javax.enterprise.inject.Produces;

class FacesContextProducer {

   @Produces @RequestScoped FacesContext getFacesContext() {
      return FacesContext.getCurrentInstance();
   }
}

2.Injecting Java EE resources into a bean

全部ManagedBean能夠利用的Java EE組件環境注入,可以使用 @Resource , @EJB, @PersistenceContext, @PersistenceUnit and @WebServiceRef.。咱們已經看到了一些這方面的例子,
@Transactional @Interceptor
public class TransactionInterceptor {

   @Resource UserTransaction transaction;

   @AroundInvoke
   public Object manageTransaction(InvocationContext ctx) throws Exception { ... }

}
@SessionScoped
public class Login implements Serializable {

   @Inject Credentials credentials;

   @PersistenceContext EntityManager userDatabase;

    ...
}

在Java EE @PostConstruct和@PreDestroy的生命週期回調也支持全部ManagedBean。全部資源注入完成後@PostConstruct方法會被調用。 java

固然,咱們建議組件環境注入是被用來定義CDI資源,而且在應用程序代碼中以類型安全的注入。

3. Calling a bean from a servlet

從Java EE的一個servlet調用一個Bean也是很容易的.只需用字段或初始化方法注入Bean.以下所示:
public class LoginServlet extends HttpServlet {

   @Inject Credentials credentials;

   @Inject Login login;

   //只是示例,實際開發要避免重寫Service方法,
   //一爲了保留HttpServlet默認實現的緩存協商的機制(HTTP 304);
   //二就是禁用你沒有在servlet中重寫的方法,例如post、head等,這樣就從必定程度上提升了安全性
   @Override
   public void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {

      credentials.setUsername(request.getParameter("username")):
      credentials.setPassword(request.getParameter("password")):
      login.login();
      if ( login.isLoggedIn() ) {

         response.sendRedirect("/home.jsp");
      }
      else {
         response.sendRedirect("/loginError.jsp");
      }
   }
}

servlet的實例共享全部傳入的線程. 緩存

4. Calling a bean from a message-driven bean

CDI注入適用於全部的EJB,甚至他們不是CDI Bean。特別是你能夠在消息驅動bean使用CDI注入.
你甚至可使用攔截器綁定消息驅動Bean。
@Transactional
@MessageDriven
public class ProcessOrder implements MessageListener {

   @Inject Inventory inventory;

   @PersistenceContext EntityManager em;

   public void onMessage(Message message) {

     ...
   }
}

請注意,消息驅動bean不能注入@SessionScoped或@ConversationScoped的Bean。只有@RequestScoped和@ApplicationScopedBean可用。 安全

5. JMS endpoints

使用JMS發送消息可能至關複雜,由於你須要處理許多不一樣的對象。queues方面的Queue,QueueConnectionFactory、QueueConnection QueueSession QueueSender。 topics方面的 topics ,TopicConnectionFactory、TopicConnection TopicSession TopicPublisher。每一個對象都有本身的生命週期和線程模型,咱們須要仔細處理這些問題, 最好的方式就是讓容器控制

咱們可使用Producer字段和方法準備全部這些資源,用於注入bean:
import javax.jms.ConnectionFactory;
import javax.jms.Queue;

public class OrderResources {

   @Resource(name="jms/ConnectionFactory")
   private ConnectionFactory connectionFactory;

   @Resource(name="jms/OrderQueue")
   private Queue orderQueue;

   @Produces
   @Order
   public Connection createOrderConnection() throws JMSException {

      return connectionFactory.createConnection();
   }

   public void closeOrderConnection(@Disposes @Order Connection connection)throws JMSException {

      connection.close();
   }

   @Produces
   @Order
   public Session createOrderSession(@Order Connection connection)throws JMSException {

      return connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
   }

   public void closeOrderSession(@Disposes @Order Session session)throws JMSException {
      session.close();
   }

   @Produces
   @Order
   public MessageProducer createOrderMessageProducer(@Order Session session)throws JMSException {

      return session.createProducer(orderQueue);
   }

   public void closeOrderMessageProducer(@Disposes @Order MessageProducer producer)throws JMSException {

      producer.close();
   }
}

使用示例: session

@Inject Order order;

@Inject @Order MessageProducer producer;

@Inject @Order Session orderSession;

public void sendMessage() {

   MapMessage msg = orderSession.createMapMessage();
   msg.setLong("orderId", order.getId());

   ...

   producer.send(msg);

}

注入的JMS對象的生命週期徹底由容器控制。 框架

6. Packaging and deployment

CDI沒有定義任何特殊的部署類型。您能夠打包成JAR文件,EJB JARs或war包.
若是使用CDI,bean.xml是必需要有的.
注意:CDI 1.1 makes use of a new XSD file for beans.xml descriptor: http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd

beans.xml文件必須位於:META-INF/beans.xml(jar包),或者,WEB-INF/beans.xml或WEB-INF/classes/META-INF/beans.xml(war包)。 jsp

Over. ide

相關文章
相關標籤/搜索