3

在 Spring 中,通过 ApplicationContext 类,我可以利用 IoC 功能并获得对 bean 的引用,如下所示

public class Driver {

    public static void main(String args[])
    {
      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-config.xml");

      MyClass myClass = (MyClass)applicationContext.getBean("myClass");

}

我希望能够对 Java EE 做同样的事情,但我似乎无法在应用程序服务器之外。

我正在尝试以下

public class Driver {

  public static void main(String args[])
  {

    InitialContext ic;

    try {

        ic = new InitialContext();
        // JNDI lookup
        MyClass myClass = (MyClass)ic.lookup("java:module/MyClass");            
    } catch (NamingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

到目前为止,通过这种方法,我得到了一个 javax.naming.NoInitialContextException。我的问题是如何在使用 Java EE 的独立应用程序中加载 IoC 功能?

编辑感谢您的帮助...我选择了 OpenWebBeans CDI 实现...感谢您的帮助。

4

3 回答 3

2

目前您正在使用JNDI,而不是 IoC。

如果您希望 JNDI 在独立应用程序中工作以查找“jndi 客户端”的远程数据谷歌。

如果您想在 Java EE 应用程序中使用 IoC - 检查CDI

于 2013-03-06T11:25:38.497 回答
0

如果您需要在 Web 容器或应用程序服务器之外获取 JNDI 资源,那么 lookup您需要绑定资源之前。但在绑定之前,您需要实现并注册javax.naming.spi.InitialContextFactory实现。

我建议以最简单的方式将所有绑定保留在全局java.util.concurrent.ConcurrentHashMap. 所以它应该如下所示(请记住,这是最简单的解决方案,在某些情况下它可能无法正常工作,但它可以满足您的特定要求):

public class Driver {

    //static initializtion
    static {
        //registering you custom InitialContextFactory
        //note, that you can register it in some other way, check http://docs.oracle.com/javase/jndi/tutorial/beyond/env/source.html
        System.setProperty("java.naming.factory.initial", SimpleInitialContextFactory.class.getName());

        bindMyClass();
    }

    private static void bindMyClass(){
        try {
            InitialContext context = new InitialContext();
            context.bind("java:module/MyClass", new MyClass());
        } catch (NamingException ignored) {}
    }

    public static void main(String args[]) throws Exception {
        InitialContext ic = new InitialContext();
            // JNDI lookup
        MyClass myClass = (MyClass)ic.lookup("java:module/MyClass");//should find it
    }
}

class SimpleInitialContextFactory implements InitialContextFactory {

        @Override
        public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
            return new MapBasedContext(environment);
        }
    }

public class MapBasedContext implements Context {
    //actual holder of context
    private static Map values = new ConcurrentHashMap();

    public MapBasedContext() {
    }

    public MapBasedContext(Hashtable<?, ?> environment) {
        values.putAll(environment);
    }

    @Override
    public void bind(String name, Object obj) throws NamingException {
        values.put(name, obj);
    }

    @Override
    public Object lookup(String name) throws NamingException {
        return values.get(name); //you may throw an exception in case if name is absent
    }

    //TODO everything else should be implemented, but actual methods bodies aren't required
}
于 2013-03-06T11:27:07.727 回答
0

CDI 是 java EE 6 中的 spring “等效”
(实际上它并不等效,因为它仅涵盖 Context 和 DI 功能,其他功能则被 EJB 或 JPA 等其他 JSR 实现所涵盖,但如果您的问题只是使用 DI 那么它会非常适合。但是,您将无法使用其他 spring / Java EE 功能,例如容器管理事务)
如果您想在独立应用程序中运行它,请继续 Jboss WELD CDI 实现。

就我个人而言,我认为对于上下文和 DI 管理来说,这比 spring 好得多,但这里不是巨魔的地方

于 2013-03-06T15:05:40.463 回答