Spring作为JNDI提供者?

我想使用Spring作为JNDI提供程序。 这意味着我想在Spring上下文中配置一个bean,可以通过JNDI访问它。 这看起来像这样:

     // rest ommitted      

然后,在我的应用程序(比如一个Controller)中,我希望能够通过以下方式获取此bean:

 Context ctx = new InitialContext(); some.thing.Else bar = (some.thing.Else) ctx.lookup("w/t/f"); 

我怎么能这样做? 我看过XBean,但项目看起来已经过时了(不适用于Spring 3.0.XI不要考虑),而且文档很少。

还有其他选择吗? 如果不是很难做的话,我还会考虑推出自己的jndi提供程序类。

编辑:我应该补充一点,我没有使用JNDI的选项,我有一个我们必须使用的库,需要通过JNDI加载某些组件。 我想使用Spring作为提供者。

为什么要使用JNDI? 只需获取Spring ApplicationContext并从中获取bean。

假设您在webapp中使用ContextLoaderListener初始化Spring,您应该能够从ServletContext中检索应用程序上下文。 从那里你可以获得你在Spring中声明的任何bean。

 ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); Object bean = context.getBean(some.thing.Else.class); 

如果必须使用JDNI,那么可以创建一个ServletContextListener,它在contextInitialized()中执行类似以下操作:

 ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext); Object bean = context.getBean(some.thing.Else.class); Context initCtx = new InitialContext(); Context springCtx = initCtx.createSubcontext("spring"); springCtx.bind("bean", bean); 

然后,您应该能够从InitialContext中的“spring / bean”中查找Spring bean。

有两点需要注意:

  1. 上下文监听器也应该也可以在contextDestroy中调用initCtx.destroySubcontext(“spring”)。

  2. java:comp / env命名空间是只读的(至少在Tomcat中),所以你不能放任何东西。

Asker编辑:还有几点清晰度……

如果您计划通过ApplicationContext引用Spring bean,那么您需要在web.xml中定义ContextLoaderListener 。 这必须在自定义侦听器类之前定义…如下所示:

  org.springframework.web.context.ContextLoaderListener    org.example.sandbox.MyCustomServletContextListener   

此外,您可以从ServletContext获取getWebApplicationContext使用的ServletContextEvent ,如下所示:

 @Override public void contextInitialized(ServletContextEvent contextEvent) { try { ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(contextEvent.getServletContext()); // get a bean named "myCalendar" from the application context Calendar cal = (Calendar)appContext.getBean("myCalendar"); // bind via JNDI Context initialContext = new InitialContext(); Context subCtx = initialContext.createSubcontext("sample"); subCtx.bind("calendar", cal); } catch (NamingException e) { // ommitted } } 

AngerClown是对的,不要打扰JNDI,除非你需要提供对其他坚持的模块的引用。 如果您在像Tomcat这样的webapp容器中,它将具有JNDI注册表。 用那个。 如果不在webapp容器中,那么无论如何都没有JNDI是没有意义的,因为它适用于J2EE环境。

假设您在webapp中,启动应用程序的更好方法是让主类成为实现生命周期接口(如InitializingBean)的Spring bean,以便在启动应用程序时进行调用。 到那时,您的主应用程序类将被注入其所有依赖项。 这避免了直接在ApplicationContext上调用方法的需要。

即便如此,如果必须在ApplicationContext上调用方法并且由Spring启动,则可以实现BeanContextAware并注入上下文。