在Java EE中与EJB交互的最佳方式
我有一个中等规模的Java EE 6项目,它使用多个EJB,其中一个目的是通过JPA管理数据库调用。 我的问题是添加一个新类的最佳方法是什么,该类执行一些随机的function,然后调用数据库访问EJB来保存此类中的数据。
如果需要访问注释和注入,这个新类必须是EJB吗? 如果必须与项目的其余部分一起部署,它是否必须是EJB?
有人告诉我,如果你想为项目添加一个新的逻辑类,它必须是一个EJB,或者你可以使用JNDI远程集成它来访问EJB元素并创建某种客户端接口。 现在我的新类只是一个POJO但它无法访问EJBfunction。
一般我该怎么办?
编辑:请注意我的问题不是数据库访问。 这只是我正在使用的一个例子。 我的猜测更广泛。 我想知道如何从我创建的其他类访问EJB方法。 从一个EJB到另一个EJB,您可以简单地注入另一个EJB,因为它们都是容器管理的。 但是说我在与EJB相同的包中创建另一个类如何才能访问这些方法? 可能吗? 这里的最佳做法是什么?
现在我有一个类从URL获取twitter feed数据,然后解析JSON并返回前10个条目的字符串。 我想调用管理数据库访问的EJB并将该字符串传递给相应的方法,但我不能这样做,因为我的类也不是EJB。
EJB通常用于实现任何类型的服务。 它们与JPA很好地集成,因此通常用于数据库访问,但这不是它们的唯一用途。
什么EJB通常不适合建模数据。 即它们应该是你的应用程序中的动词,而不是名词。 以下是错误的 :
@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 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请求参数 )
通过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 openInvoices = invoiceDAO.getAllByOpenStatus(); // verbose exception handling and closing JNDI context omitted for brevity } }
前面显示的@Singleton bean是一个Java EE框架在启动时如何调用代码本身的示例。 对于自动计时器,您可以在bean的方法上使用@Schedule注释。