首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >EJB工厂类

EJB工厂类
EN

Stack Overflow用户
提问于 2009-08-06 14:07:06
回答 4查看 5.6K关注 0票数 2

我正在尝试创建一个EJB工厂类,它的工作原理如下:您有一个以EJB的类为参数的方法,然后它检查EJB是否有远程接口(如果没有抛出异常),如果有,则返回相关的EJB。

下面的代码就是这样做的。但是,它返回的对象是相关bean的远程接口的类型,而不是bean本身的类型。我怎样才能改变这一点?有没有办法告诉Java泛型类型T与传递给方法的类属于同一类型。

代码语言:javascript
复制
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;
    }

}

使用工厂的单元测试示例。

代码语言:javascript
复制
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工作,我没有使用任何其他应用服务器对其进行测试。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-08-17 18:10:30

EJB的客户端通过EJB实现的本地/远程接口与之交互。客户端应用程序永远不能直接访问实际的会话bean类实例。这样做是为了使实例池成为可能,其中容器可以重用EJB实例来服务不同的请求。

我不确定为什么需要访问实际bean的对象(因为很明显,我不知道您的需求)。但是如果您仍然需要创建一个实例,您可以按如下所示使用反射EJB来完成此操作,这样创建的实例不是Class.forName(className).newInstance();。这只是一个POJO,仅此而已。

EJB编辑-在您关于junit测试的评论之后:当您按如下方式从JavaSE访问业务方法时,您实际上是在调用中的方法-只是您通过接口进行交互。因此,如果您想测试任何业务方法,仍然可以从Junit测试中通过JNDI查找获得的对象进行测试。

代码语言:javascript
复制
//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.forName创建一个实例……就像我上面提到的。当您创建这样的实例时,您只能调用不做任何"Java“工作的方法。例如,您可以调用EJB类中的方法,如下所示

代码语言:javascript
复制
public String someMethod(){
       return "I am a POJO but I look like an EJB";
}
票数 3
EN

Stack Overflow用户

发布于 2009-08-06 14:51:44

我不认为您可以获得EJB对象。您只能获取接口。应该使用接口调用createEJB,它会返回接口。

票数 1
EN

Stack Overflow用户

发布于 2009-08-06 14:23:42

尝试替换

代码语言:javascript
复制
public <T> T createEJB(Class ejbClass) throws NamingException

使用

代码语言:javascript
复制
public <T> T createEJB(Class<T> ejbClass) throws NamingException
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1239116

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档