Spring & JNDI:定位资源平台无关

Spring & JNDI: locate resource platform independent

我正在尝试加载 JNDI 提供的 属性 文件,该文件应该与平台无关。我知道我可以通过以下方式完成,具体取决于平台:

对于 Weblogic:

Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
InitialContext context = new InitialContext(properties);
context.lookup(propertiesLocation);

对于Tomcat:

Context context = new InitialContext();
Context envCtx = (Context) context.lookup("java:comp/env");
final Object lookup = envCtx.lookup(propertiesLocation);

核心问题是在Tomcat中需要前缀java:comp/env/。由于 Spring 能够独立加载所有这个平台,我尝试研究 Spring 加载我的 JNDI 资源的可能性。

我发现我可以通过以下方式使用 Spring 的 JndiTemplate

JndiTemplate jndiTemplate = new JndiTemplate();
Object lookup = jndiTemplate.lookup(propertiesLocation);

然而,这仍然取决于平台,需要在查找 tomcat 期间使用 java:comp/env 作为前缀。进一步查看 WhosebugSpring javadocs,我发现 class JndiLocatorSupport,其中包含以下内容:

JNDI names may or may not include the "java:comp/env/" prefix expected by J2EE applications when accessing a locally mapped (ENC - Environmental Naming Context) resource. If it doesn't, the "java:comp/env/" prefix will be prepended if the "resourceRef" property is true (the default is false) and no other scheme (e.g. "java:") is given.

所以我创建了一个扩展 JndiLocatorSupportJndiObjectFactoryBean,启用了 setResourceRef 但它似乎没有附加前缀。

核心问题:
使用以下代码时:

JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
factoryBean.setResourceRef(true);
Object lookup = factoryBean.getJndiTemplate().lookup(propertiesLocation);

我希望它具有与以下相同的效果:

JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
Object lookup = factoryBean.getJndiTemplate().lookup("java:comp/env/" + propertiesLocation);

但事实并非如此。好像一点作用都没有。但是如果我查看源代码,它确实是这样的: JndiObjectFactoryBean.lookup() -> JndiObjectLocator.lookup() -> JndiLocatorSupport.lookup()does call 正确的方法。

JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
factoryBean.setResourceRef(true);
Object lookup = factoryBean.getJndiTemplate().lookup(propertiesLocation);

JndiTemplate jndiTemplate = new JndiTemplate();
Object lookup = jndiTemplate.lookup(propertiesLocation);

查找方面相同。第一个只是一个很复杂的获取方式JndiTemplate。您所做的所有设置都是针对 JndiObjectFactoryBean 而不是针对内部 JndiTemplate。基本上你的整个方法不会增加任何东西。

而是使用 JndiLocatorDelegate 并让它进行查找(不要尝试获取 JndiTemplate!)。

JndiLocatorDelegate jndi = JndiLocatorDelegate.createDefaultResourceRefLocator();
Object lookup = jndi.lookup(propertiesLocation);

默认情况下,这将在 java:comp/env 中进行查找,如果未找到,则回退到普通的 propertiesLocation(您传入的内容)。