想象一下,您有两个@Local
接口
@Local
public interface LocalInterface {
}
@Stateless
public class MyFirstImplementation implements LocalInterface {
}
@Stateless
public class MySecondImplementation implements LocalInterface {
}
我想选择而不重新编译项目(即在运行时或使用外部配置属性)我想使用哪个(MyFirstImplementation或MySecondImplementation)。
public class MyClass {
@EJB
LocalInterface local;
}
一旦选择了一个实现,就不必更改。如果有帮助,我正在使用JBoss 5.1。
答案 0 :(得分:2)
您可以使用部署描述符ejb-jar.xml来实现它。这样的事情(可能不是100%准确,但我认为你已经明白了):
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>MyClass</ejb-name>
<ejb-ref>
<ejb-ref-name>ejb/myLocalReferencedBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>com.yourpackage.LocalInterface</local>
<ejb-link>MyFirstImplementation</ejb-link>
<injection-target>local</injection-target>
</ejb-ref>
</session>
<session>
<ejb-name>MyFirstImplementation</ejb-name>
<!-- ... -->
</session>
<session>
<ejb-name>MySecondImplementation</ejb-name>
<!-- ... -->
</session>
</enterprise-beans>
</ejb-jar>
另一种方法是使用此处所述的CDI:Inject @EJB bean based on conditions
答案 1 :(得分:2)
另一种方法是使用JNDI查找EJB引用,而不是依赖于自动注入,以防它可以帮助其他任何人:
public class MyClass {
LocalInterface local;
@PostConstruct
public void init() {
local = findImplementation();
}
private LocalInterface findImplementation() {
try {
InitialContext context = new InitialContext();
String ejbPath = // read from an external property
return (LocalInterface) context.lookup(ejbPath);
} catch ... { ... }
}
}
这是我最终做的,因为使用JBoss 5(&lt; Java EE 6,EJB 3.0),您无法使用有用的@Produces
注释。如果您没有其他限制,我将PedroKowalski's answer设置为CDI注释似乎是更好的解决方案。
答案 2 :(得分:1)
PedroKowalski概述的方法是一种典型的方法。关于“外部配置属性”的另一个技巧是简单地配置构建器,使得只有1个实现在您生成的容纳EJB的jar中结束。
因此您不必重新编译类或更改任何源代码,但您必须重建jar以选择其他实现。