EJB 通常用于实现任何类型的服务。它们与 JPA 集成得非常好,因此经常用于数据库访问,但这并不是它们的唯一用途。
EJB 通常是什么not适用于建模数据。 IE。它们应该是应用程序中的动词,而不是名词。因此以下是wrong:
@Stateless
@Entity
public class CreditCard { // silly, don't do this!
@Id
Long id; + getters/setters
Data expiration date; + getters/setters
}
下面的更好,它是一项服务,当您的应用程序启动时,它会从某处获取一些报价数据:
@Singleton
@Startup
public class QuoteFetcher {
private List<Quote> quotes; // + getter
@PostConstruct
public fetchQuote()
quotes = SomeUrlBuilder.someUrl().getQuotes();
}
}
以下是强制性 DAO 示例:
@Stateless
public class JPAInvoiceDAO implements InvoiceDAO {
@PersistenceContext
private EntityManager entityManager;
public Invoice getById(Long invoiceId) {
return entityManager.find(invoiceId, Invoice.class);
}
// More DAO methods
}
下面显示了如何使用声明性安全性,以及 Bean 如何查找已从外部映射到其私有上下文 (ENC) 的内容:
@Stateless
public class TokenFetcher
@Resource
private SessionContext sessionContext;
@RolesAllowed("SYSTEM")
public Token getToken() {
return (Token) sessionContext.lookup("token");
}
}
问题的第二部分似乎是如何在代码中使用这些 bean。基本上有四种方法:
- 注入托管 Bean
- 通过 JNDI 引导
- 启动时自动调用
- 通过定时器自动
注入是最简单的方法,但只有托管 bean 才是注入候选者(基本上意味着 Java EE 框架创建 bean,并且您不使用new()
实例化它)。
例如。注射:
@ManagedBean
public class InvoiceBacking {
private Long invoiceId; // + getter/setter
private Invoice invoice; // + getter
@EJB
private InvoiceDAO invoiceDAO;
@PostConstruct
public void init() {
invoice = invoiceDAO.getById(invoiceId);
}
}
(另见JSF 2.0中的通信#处理GET请求参数 http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#ProcessingGETRequestParameters)
通过 JNDI 引导:
public class SomeQuartzJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
InvoiceDAO invoiceDAO = (InvoiceDAO) new InitialContext().lookup("java:global/myApp/myEJB/InvoiceDAO");
List<Invoice> openInvoices = invoiceDAO.getAllByOpenStatus();
// verbose exception handling and closing JNDI context omitted for brevity
}
}
前面展示的 @Singleton bean 是 Java EE 框架如何在启动时调用代码本身的示例。对于自动计时器,您可以在 bean 的方法上使用 @Schedule 注释。