2013-03-06 112 views
3

在春天通過的ApplicationContext類我可以利用的IoC功能,並得到一個參考的Bean如下的Spring IoC和Java EE

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實施...感謝您的幫助。

回答

2

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

如果您希望JNDI在獨立應用程序中爲「jndi客戶端」定位遠程數據谷歌。

如果你想在您的Java EE應用程序使用的IoC - 檢查CDI

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 
} 
+0

嗨的地方,感謝您的回答。我試過這個,但它仍然拋出命名異常。 「需要在環境或系統屬性中指定類名稱,或者作爲小程序參數」。 – Barry 2013-03-06 11:43:14

+0

@Barry,在這種情況下,我怕你需要實現'javax.naming.spi.InitialContextFactory'並把它放到系統屬性中。我在更新後的答案中提供了非常相似的內容。 – n1ckolas 2013-03-06 13:05:31

0

CDI是彈簧「等價「(實際上它不是等價的,因爲它只包含Context和DI的特性,其他的則被其他的JSR實現所覆蓋,比如EJB或者JPA,但是如果你的問題只是使用DI,那麼它將完全適合。您將不能使用Spring/Java EE的其他功能,例如容器管理事務)
如果您想在獨立應用程序中運行它,請繼續Jboss WELD CDI實現。

我個人認爲這是它的farly比春天的語境和DI管理更好,但這裏不是巨魔