SeamFramework.orgCommunity Documentation
Web Beans被完全地整合进了Java EE环境里。Web Beans 能够访问Java EE资源和JPA持久化上下文。它们可以在JSF和JSP页面中的统一表达式语言使用。它们甚至可以被注入到一些对象中,例如Servlet和消息驱动Bean,而这些对象都不是Web Bean。
所有简单的和企业的Web Beans都可以通过@Resource
, @EJB
和@PersistenceContext
来使用Java EE的依赖注入。我们已经看过很多例子了,虽然我们没有在这上面耗费精力:
@Transactional @Interceptor
public class TransactionInterceptor {
@Resource Transaction transaction;
@AroundInvoke public Object manageTransaction(InvocationContext ctx) { ... }
}
@SessionScoped
public class Login {
@Current Credentials credentials;
@PersistenceContext EntityManager userDatabase;
...
}
所有的简单的和企业的Web Beans都支持Java EE的@PostConstruct
和@PreDestroy
回调。@PostConstruct
方法在所有的 注入完成后被调用。
这里需要注意的一个限制是:简单的Web Beans不支持 @PersistenceContext(type=EXTENDED)
在Java EE 6中,从一个Servlet中调用一个Web Bean非常容易,只须使用Web Beans域注入一个Web Bean或者将初始方法注入即可。
public class Login extends HttpServlet {
@Current Credentials credentials;
@Current Login login;
@Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
credentials.setUsername( request.getAttribute("username") ):
credentials.setPassword( request.getAttribute("password") ):
login.login();
if ( login.isLoggedIn() ) {
response.sendRedirect("/home.jsp");
}
else {
response.sendRedirect("/loginError.jsp");
}
}
}
Web Beans客户端代理将Servlet中的方法调用路由到当前请求和HTTP会话中相应的Credentials
和 Login
实例。
Web Beans注入可以应用于所有的EJB,甚至这些EJB不在Web Bean管理器的控制之下也可以(如果它们可以直接从JNDI查找或者使用@EJB
注入)。消息驱动Bean不能成为Web Beans,因为你无法注入它们,但你仍然可以将Web Beans注入到消息驱动Bean中。
你甚至可以将Web Beans拦截器绑定到消息驱动Bean上。
@Transactional @MessageDriven
public class ProcessOrder implements MessageListener {
@Current Inventory inventory;
@PersistenceContext EntityManager em;
public void onMessage(Message message) {
...
}
}
这样,在一个Web Beans环境中接受消息就相当简单了。但是需要注意的是,当一个消息发送到一个消息驱动Bean的时候,此时没有会话,我们无法获得对话上下文。我们只能获得 @RequestScoped
和 @ApplicationScoped
注释的Web Beans。
使用Web Beans发送消息也相当简单。
使用JMS发送消息有点复杂,因为你需要处理很多不同的对象。对于队列(Queue),我们有Queue
, QueueConnectionFactory
, QueueConnection
, QueueSession
和 QueueSender
。对于主题(Topic)有Topic
, TopicConnectionFactory
, TopicConnection
, TopicSession
和 TopicPublisher
。这些对象每个都有自己的生命周期和线程模型,我们都需要考虑这些问题。
Web Beans为我们处理所有这些问题。我们只须在 web-beans.xml
声明队列或者主题,指定一个关联的绑定类型和连接工厂即可。
<Queue>
<destination
>java:comp/env/jms/OrderQueue</destination>
<connectionFactory
>java:comp/env/jms/QueueConnectionFactory</connectionFactory>
<myapp:OrderProcessor/>
</Queue
>
<Topic>
<destination
>java:comp/env/jms/StockPrices</destination>
<connectionFactory
>java:comp/env/jms/TopicConnectionFactory</connectionFactory>
<myapp:StockPrices/>
</Topic
>
现在,对于队列,我们只须注入 Queue
, QueueConnection
, QueueSession
或者 QueueSender
;对于主题,我们只须注入Topic
, TopicConnection
, TopicSession
或者 TopicPublisher
。
@OrderProcessor QueueSender orderSender;
@OrderProcessor QueueSession orderSession;
public void sendMessage() {
MapMessage msg = orderSession.createMapMessage();
...
orderSender.send(msg);
}
@StockPrices TopicPublisher pricePublisher;
@StockPrices TopicSession priceSession;
public void sendMessage(String price) {
pricePublisher.send( priceSession.createTextMessage(price) );
}
被注入的JMS对象的生命周期完全由Web Bean管理器控制。