简体   繁体   English

Spring IoC和Java EE

[英]Spring IoC and Java EE

In Spring through the ApplicationContext class I can utilise IoC features and get a reference to a bean as follows 在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");

}

I would like to be able to do the same with Java EE, but I don't seem to be able to outside of an application server. 我希望能够对Java EE做同样的事情,但我似乎无法在应用程序服务器之外。

I'm trying the following 我正在尝试以下方法

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();
    }


}

So far with this approach I get a javax.naming.NoInitialContextException. 到目前为止,通过这种方法,我得到了一个javax.naming.NoInitialContextException。 My question is how can load up IoC features in a standalone application using Java EE? 我的问题是如何在使用Java EE的独立应用程序中加载IoC功能?

EDIT Thanks for the help guys...I went with the OpenWebBeans CDI implementation... Thanks for the help. 编辑感谢帮助人...我参加了OpenWebBeans CDI实施...感谢您的帮助。

Currently you are working with JNDI , not an IoC. 目前您正在使用JNDI ,而不是IoC。

If you want JNDI worked in standalone application to locate remote data google for "jndi client". 如果您希望JNDI在独立应用程序中工作,可以为“jndi客户端”找到远程数据谷歌。

If you want to use IoC in your Java EE application - check CDI 如果要在Java EE应用程序中使用IoC,请检查CDI

If you need to get JNDI resource outside web-container or application server, then before lookup you need to bind resource. 如果需要在Web容器或应用程序服务器之外获取JNDI资源,那么 lookup 之前需要绑定资源。 But before binding you need to implement and register javax.naming.spi.InitialContextFactory implementation. 但在绑定之前,您需要实现并注册javax.naming.spi.InitialContextFactory实现。

In the easiest way I would suggest to keep all bindings in the global java.util.concurrent.ConcurrentHashMap . 以最简单的方式,我建议将所有绑定保存在全局java.util.concurrent.ConcurrentHashMap So it should look like the following (please keep in mind that this is easiest solution, and it might not work properly in some cases, but it satisfies your particular request): 所以它应该如下所示(请记住,这是最简单的解决方案,在某些情况下它可能无法正常工作,但它满足您的特定请求):

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
}

CDI is the spring "equivalent" in java EE 6 CDI是java EE 6中的“等效”弹簧
(in fact it is not equivalent cause it covers only Context and DI features, the others one are covered by other JSR implementation like EJB or JPA but if your problem is only to use DI then it will fit perfectly. You won't be able however to use others spring / Java EE features like Container managed transaction for example) (实际上它并不等同,因为它只涵盖了Context和DI功能,其他一个被EJB或JPA等其他JSR实现覆盖,但是如果你的问题只是使用DI那么它将完全适合。你将无法但是要使用其他spring / Java EE功能,例如Container托管事务)
If you want to run it in a standalone application, go on Jboss WELD CDI implementation. 如果要在独立应用程序中运行它,请继续使用Jboss WELD CDI实现。

Personally i think that's it's farly better than spring for Context and DI management, but here's not the place to troll 就个人而言,我认为这对于Context和DI管理来说远胜于春天,但这里不是巨魔的地方

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM