如何在声明中将(绑定)对象放到jndi中?
我们有一个普通的独立spring应用程序,我们需要将jdbc数据源放在jndi中。 (我们使用jboss treecache,它需要数据源在jndi中)。
一些谷歌搜索发现大多数jndi查找示例与spring,其中一个对象已经放在jndi(通过tomcat或应用程序服务器等),但我们需要:我有一个简单的数据源Spring bean,我注入其他服务,但我无法将其注入TreeCache,因为它只需要来自jndi。
找到org.springframework.jndi.JndiTemplate
,可以声明为bean,例如:
com.sun.jndi.fscontext.RefFSContextFactory file:///c:\windows\temp
但是没有找到如何在java代码中绑定它: fsJndiTemplate.bind(name, obj)
来自其他bean的init-method。 有没有办法以声明方式做到这一点?
您可以创建一个JndiExporter,它使用JndiTemplate将对象的地图与名称绑定在一起:
您的JndiExporter必须实现BeanFactoryAware以使用注入的BeanFactory检索spring bean。
这是一个可能的:)
谢谢你的问题。 我写了一个Treydone解决方案的变体,并认为在这里使用实际代码可能很有用(因为它很短):
public class JndiExporter implements InitializingBean { private final JndiTemplate template = new JndiTemplate(); private Map jndiMapping = null; @Override public void afterPropertiesSet() throws Exception { for(Entry addToJndi: jndiMapping.entrySet()){ template.bind(addToJndi.getKey(), addToJndi.getValue()); } } public void setJndiMapping(Map jndiMapping) { this.jndiMapping = jndiMapping; } }
请注意,我实现了InitializingBean而不是BeanFactoryAware。 这允许配置(带引用),如下所示:
我意识到这是一个老问题,但有一种方法可以在没有自定义代码的情况下完成此操作。 它相当冗长,但100%声明。
java:comp/UserTransaction another/jndi/name literal_value
只要读取System属性的bean depends-on
MethodInvokingFactoryBean
, MethodInvokingFactoryBean
也可用于设置系统属性( 在使用Atomikos时派上用场 )。
true true com.atomikos.icatch.standalone.UserTransactionServiceFactory /opt/txlogs
嗨此问题没有标准或最佳实践类型方法。 您将拥有自己的方法。 以下是另一种可以解决您的问题的方法。
-
使javax.naming.InitialContext成为一个spring bean(比如initialContext)。 确保根据需要向其传递适当的初始属性映射。
-
现在创建另一个bean说JndiBinder。 在这个bean中注入上面提到的#1 bean。 这个bean将获取jndi-names和相应对象的映射。 对于您的情况,该对象将是数据源,已在spring上下文中可用。
-
在JndiBinder bean定义中,编写一个init方法,该方法将为地图中的所有条目(jndi-names和相应对象)调用initialContext的bind menthod。 这样,提供的映射中的所有条目都绑定到JNDI树。
如果代码在Servlet容器外部执行,例如在unit testing中,则需要模拟JNDI上下文。 否则你会得到可怕的“需要在环境中指定类名…”错误。
SimpleNamingContextBuilder比JndiTemplate更适合:
public class JndiExporter implements InitializingBean { private final SimpleNamingContextBuilder contextBuilder = new SimpleNamingContextBuilder(); private Map jndiMapping = null; @Override public void afterPropertiesSet() throws Exception { for (Entry addToJndi : jndiMapping.entrySet()) { contextBuilder.bind(addToJndi.getKey(), addToJndi.getValue()); } contextBuilder.activate(); } public void setJndiMapping(Map jndiMapping) { this.jndiMapping = jndiMapping; }
不要忽视“contextBuilder.activate();” 线。