我想使用Spring作为JNDI提供程序.这意味着我想在Spring上下文中配置一个bean,可以通过JNDI访问它.这看起来像这样:
<bean class="org.some.thing.here">
<property name="beans">
<map>
<entry key="w/t/f">
<bean class="some.thing.Else">
// rest ommitted
</bean>
</entry>
</map>
</property>
</bean>
然后,在我的应用程序(比如一个Controller)中,我希望能够通过以下方式获取此bean:
Context ctx = new InitialContext();
some.thing.Else bar = (some.thing.Else) ctx.lookup("w/t/f");
我怎么能这样做?我看过XBean,但项目看起来已经过时了(不适用于Spring 3.0.X我不认为),而且文档很少.
还有其他选择吗?如果不是很难做的话,我也会考虑推出自己的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.
有两点需要注意:
>上下文监听器也应该也可以在contextDestroy中调用initCtx.destroySubcontext(“spring”).
> java:comp / env命名空间是只读的(至少在Tomcat中),所以你不能放任何东西.
Asker编辑:还有几点清晰度……
如果您计划通过ApplicationContext引用Spring bean,那么您需要在web.xml中定义ContextLoaderListener.这必须在自定义侦听器类之前定义…如下所示:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.example.sandbox.MyCustomServletContextListener
</listener-class>
</listener>
此外,您可以从ServletContextEvent获取getWebApplicationContext使用的ServletContext,如下所示:
@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 }
}