我对 EJB 和 JBoss 等成熟的应用服务器相当陌生,在我职业生涯的大部分时间里,我都在编写和使用特殊用途的独立 Java 应用程序,但对 Java EE 的使用有限。我想知道使常用设计模式适应 EJB3 和 JBoss 的最佳方法:静态工厂模式。事实上,这是 Joshua Bloch 的 Effective Java 书(第 2 版)中的第 1 项
我目前在以下工厂工作:
public class CredentialsProcessorFactory {
private static final Log log = LogFactory.getLog(CredentialsProcessorFactory.class);
private static Map<CredentialsType, CredentialsProcessor> PROCESSORS =
new HashMap<CredentialsType, CredentialsProcessor>();
static {
PROCESSORS.put(CredentialsType.CSV, new CSVCredentialsProcessor());
}
private CredentialsProcessorFactory() {}
public static CredentialsProcessor getProcessor(CredentialsType type) {
CredentialsProcessor p = PROCESSORS.get(type);
if(p == null)
throw new IllegalArgumentException("No CredentialsProcessor registered for type " + type.toString());
return p;
}
但是,在 CredentialsProcessor 的实现类中,我需要注入(inject)资源,例如 PersistenceContext
,因此我将 CredentialsProcessor
接口(interface)设为 @Local
接口(interface),每个 impl 都标有 @Stateless
。现在我可以在 JNDI 中查找它们并使用注入(inject)的资源。
但现在我断开连接了,因为我不再使用工厂了。我的第一个想法是更改 getProcessor(CredentialsType)
方法以执行 JNDI 查找并返回所需的 SLSB 实例,但随后我需要配置并传递正确的限定 JNDI 名称。在我走这条路之前,我想对公认的做法做更多的研究。
EJB3/Java EE 如何处理这种设计模式?-
最佳答案
当您开始使用工厂和“真正的”Java POJO 代码时,您基本上需要依赖 JNDI。
依赖注入(inject)仅适用于 EJB 服务器的托管组件,基本上就是 Servlet 和 EJB。
当您谈论想要引用 EJB 的通用 Java 代码时,它们需要通过 JNDI 自行查找资源。
在这种情况下,最好的做法是简单地编写一个包含静态函数的包装器查找类来执行 JNDI 查找,而不是在每个实现中直接调用 JNDI。然后在您的实现中使用它。
这只是一个通用的总体规则。
现在,针对您的具体情况,考虑这一点。
你有:
static {
PROCESSORS.put(CredentialsType.CSV, new CSVCredentialsProcessor());
}
这与以下内容没有区别:
static {
PROCESSORS.put(CredentialsType.CSV, "java:comp/env/ejb/CSVCredentialProcessorSessionBean");
}
然后,在您的 getProcessor() 代码中:
Context c = new InitialContext();
return (CredentialsProcessor) c.lookup(PROCESSORS.get(type));
看,基本上,代码是相同的,您的工厂接口(interface)对客户端也是相同的。
您必须“硬编码”JNDI 查找键,但无论如何您现在正在“硬编码”类名,那么这有何不同?
跨容器存在一些潜在的可移植性问题,因为每个人似乎都喜欢对 bean 名称使用不同的 JNDI 标识符。其中大部分可以在部署中进行调整,但如果不能,那么您可以将这些 key 提取到配置文件或其他任何文件中。
在 Java EE 6 中,有保证的可移植名称。如果您今天不移植容器,那么根本不用担心这个。
所以,基本上,这根本不是真正的脱节。
关于java - 带有 EJB3/JBoss 的 avaStatic 工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2541875/