我正在尝试创建一个 EJB 工厂类,其工作方式如下:您有一个方法,该方法将 EJB 的类作为参数,然后它检查 EJB 是否具有远程接口(如果没有抛出异常),以及是否有远程接口。确实如此,它返回相关的 EJB。
下面的代码正是这样做的。然而,它返回的对象是相关 bean 的远程接口的类型,而不是 bean 本身的类型。我怎样才能改变这个?有没有办法告诉 Java 泛型类型 T 与传递给方法的类具有相同的类型。
import java.util.Properties;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.naming.*;
public class EJBFactory
{
private InitialContext ctx;
public EJBFactory() throws NamingException {
ctx = new InitialContext();
}
public EJBFactory(String host, String port) throws NamingException {
Properties props = new Properties();
props.setProperty("org.omg.CORBA.ORBInitialHost", host);
props.setProperty("org.omg.CORBA.ORBInitialPort", port);
ctx = new InitialContext(props);
}
.
// To improve: The object returned should be of the type ejbClass
// instead of the remote interface, which it implements
public <T> T createEJB(Class ejbClass) throws NamingException
{
Class remoteInterface = null;
for(Class interface_: ejbClass.getInterfaces()) {
if(interface_.isAnnotationPresent(Remote.class))
remoteInterface = interface_;
}
if(remoteInterface == null)
throw new IllegalArgumentException(
"EJB Requires a remote interface");
// Get the stateless annotation, then get the jndiName
Stateless stateless =
(Stateless)ejbClass.getAnnotation(Stateless.class);
String jndiName = stateless.mappedName();
T ejbObj = (T) ctx.lookup(jndiName);
return ejbObj;
}
}
使用工厂的单元测试示例。
import junit.framework.TestCase;
public class SimpleEJBTest extends TestCase
{
TestRemote testBean;
@Override
protected void setUp() throws Exception {
super.setUp();
EJBFactory ejbFactory = new EJBFactory();
testBean = ejbFactory.createEJB(TestBean.class);
}
public void testSayHello() {
assertEquals("Hello", testBean.sayHello());
}
}
注意:该示例适用于 Glassfish,我没有使用任何其他应用程序服务器对其进行测试。
EJB 的客户端通过 EJB 实现的本地/远程接口与它们交互。客户端应用程序永远无法直接访问实际的会话 bean 类实例。这样做是为了使实例池成为可能,容器可以重用 EJB 实例来服务不同的请求。
我不确定为什么您需要访问实际 bean 的对象(因为显然我不知道您的要求)。但如果您仍然需要创建一个实例,您可以使用反射按如下方式完成Class.forName(className).newInstance();
同样,您像这样创建的实例不是 EJB。它只是一个 POJO,仅此而已。
EDIT- 在您对 junit 测试发表评论之后:当您按如下方式从 JavaSE 访问业务方法时,您实际上是在调用 EJB 中的方法 - 只是通过接口进行交互。因此,如果您想测试任何业务方法,您仍然可以通过在 Junit 测试中通过 JNDI 查找获得的对象来进行测试。
//MyGreatBean implements MyGreat. MyGreat has @Remote, MyGreatBean has @Stateless
ref = jndiContext.lookup("MyGreatBean/remote");
MyGreat bean = (MyGreat) ref;
String retValue = bean.businessMethod();
assertEquals("Success", retValue);
从之前的评论中,我感觉到您想要检查实际 EJB 类中添加了哪些类型的注释 - 如果您想在不实际运行业务方法的情况下进行此类检查,则可以使用 Class.eJB 类创建一个实例。 forName...就像我上面提到的那样。当您创建这样的实例时,您只能调用不执行任何“Java EE”操作的方法。例如,您可以调用 EJB 类中的方法,如下所示
public String someMethod(){
return "I am a POJO but I look like an EJB";
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)