java Spring 作为 JNDI 提供者?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4414115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring as a JNDI provider?
提问by Polaris878
I would like to use Spring as a JNDI provider. This means that I would like to configure a bean in my Spring context, which can be accessed via JNDI. This would look something like this:
我想使用 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>
Then, in my application (lets say a Controller), I want to be able to grab this bean via:
然后,在我的应用程序(假设是一个控制器)中,我希望能够通过以下方式获取这个 bean:
Context ctx = new InitialContext();
some.thing.Else bar = (some.thing.Else) ctx.lookup("w/t/f");
How could I go about doing this? I've looked at XBean, however the project looks out of date (doesn't work with Spring 3.0.X I don't think), and there is very little documentation.
我怎么能去做这件事?我看过XBean,但是这个项目看起来已经过时了(不认为Spring 3.0.XI 不工作),而且文档很少。
Any other options? I would also considering rolling my own jndi provider class if it isn't too hard to do.
还有其他选择吗?如果不太难的话,我也会考虑滚动我自己的 jndi 提供程序类。
EDIT:I should add that I don't have an option using JNDI, I have a library we have to use which requires certain components to be loaded via JNDI. I would like to use Spring as the provider.
编辑:我应该补充一点,我没有使用 JNDI 的选项,我有一个我们必须使用的库,它需要通过 JNDI 加载某些组件。我想使用 Spring 作为提供者。
回答by AngerClown
Why use JNDI at all? Just get the Spring ApplicationContext and get the bean from that.
为什么要使用 JNDI?只需获取 Spring ApplicationContext 并从中获取 bean。
Assuming you initialized Spring using ContextLoaderListener in your webapp, you should be able to retrieve the application context from the ServletContext. From there you can get any bean you declared in Spring.
假设您在 web 应用程序中使用 ContextLoaderListener 初始化 Spring,您应该能够从 ServletContext 检索应用程序上下文。从那里你可以得到你在 Spring 中声明的任何 bean。
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Object bean = context.getBean(some.thing.Else.class);
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Object bean = context.getBean(some.thing.Else.class);
If you have to use JDNI, then you can create a ServletContextListener that does something like the following in contextInitialized():
如果您必须使用 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);
Then, you should be able to lookup the Spring bean at "spring/bean" from the InitialContext.
然后,您应该能够从 InitialContext 中的“spring/bean”中查找 Spring bean。
Two things to note:
有两点需要注意:
The context listener should probably also call initCtx.destroySubcontext("spring") in contextDestroy too.
The java:comp/env namespace is read-only (in Tomcat at least), so you can't put anything there.
上下文侦听器也应该在 contextDestroy 中调用 initCtx.destroySubcontext("spring") 。
java:comp/env 命名空间是只读的(至少在 Tomcat 中),所以你不能在那里放任何东西。
Asker edit:Just a couple more points of clarity...
提问者编辑:再澄清几点……
If you plan on referencing Spring beans via ApplicationContext
, then you need a ContextLoaderListener
defined in your web.xml. This must be defined before your custom listener class... like so:
如果您计划通过 引用 Spring bean ApplicationContext
,那么您需要ContextLoaderListener
在 web.xml 中定义一个。这必须在您的自定义侦听器类之前定义......像这样:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.example.sandbox.MyCustomServletContextListener
</listener-class>
</listener>
Also, you can get the ServletContext
that getWebApplicationContext
uses from the ServletContextEvent
, like so:
此外,你可以得到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 }
}
回答by Brian Topping
AngerClown is right, don't bother with JNDI unless you need to provide references to other modules that insist on it. If you are in a webapp container like Tomcat, it will have a JNDI registry. Use that. If not inside a webapp container, it doesn't make sense to have JNDI anyway, since it's for J2EE environments.
AngerClown 是对的,除非您需要提供对其他坚持它的模块的引用,否则不要打扰 JNDI。如果您在像 Tomcat 这样的 webapp 容器中,它将有一个 JNDI 注册表。用那个。如果不在 webapp 容器内,那么无论如何拥有 JNDI 都没有意义,因为它用于 J2EE 环境。
Assuming you are inside a webapp, a better way to launch your app is to have the main class be a Spring bean that implements lifecycle interfaces (like InitializingBean) to get a call when it's time to start your app. By that point, your main application class will have been injected with all it's dependencies. This avoids the need to call methods on the ApplicationContext directly.
假设您在一个 web 应用程序中,启动应用程序的更好方法是让主类是一个 Spring bean,它实现了生命周期接口(如 InitializingBean),以便在启动应用程序时获得调用。到那时,您的主应用程序类将被注入它的所有依赖项。这避免了直接在 ApplicationContext 上调用方法的需要。
Even so, if you must call methods on the ApplicationContext and you are launched by Spring, you can implement BeanContextAware and get injected with the context.
即便如此,如果您必须在 ApplicationContext 上调用方法并且您由 Spring 启动,您可以实现 BeanContextAware 并注入上下文。
回答by Mikhail Kolesnikov
Yet another way to write your own JndiExporter
另一种编写自己的 JndiExporter 的方法
https://blog.konstantinpavlov.net/2008/12/31/how-to-export-spring-bean-to-jndi/
https://blog.konstantinpavlov.net/2008/12/31/how-to-export-spring-bean-to-jndi/