3 回答
TA贡献1777条经验 获得超10个赞
默认情况下,JNDI在嵌入式Tomcat中处于禁用状态,这会导致NoInitialContextException。您需要致电Tomcat.enableNaming()将其启用。最简单的方法是使用TomcatEmbeddedServletContainer子类:
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
};
}
如果采用这种方法,则也可以DataSource通过重写子类中的postProcessContext方法在JNDI中注册TomcatEmbeddedServletContainerFactory。
context.getNamingResources().addResource将资源的java:comp/env背景下,因此资源的名称应该是jdbc/mydatasource没有java:comp/env/mydatasource。
Tomcat使用线程上下文类加载器来确定应针对哪个JNDI上下文执行查找。您将资源绑定到Web应用程序的JNDI上下文中,因此需要确保在Web应用程序的类加载器是线程上下文类加载器时执行查找。您应该可以通过将设置lookupOnStartup为来实现此false目的jndiObjectFactoryBean。您还需要设置expectedType为javax.sql.DataSource:
<bean class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/mydatasource"/>
<property name="expectedType" value="javax.sql.DataSource"/>
<property name="lookupOnStartup" value="false"/>
</bean>
这将为DataSource创建代理,并在首次使用时而不是在应用程序上下文启动期间执行实际的JNDI查找。
在Spring Boot示例中说明了上述方法。
TA贡献1831条经验 获得超4个赞
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
ContextResource resource = new ContextResource();
resource.setName("jdbc/myDataSource");
resource.setType(DataSource.class.getName());
resource.setProperty("driverClassName", "your.db.Driver");
resource.setProperty("url", "jdbc:yourDb");
context.getNamingResources().addResource(resource);
}
};
}
@Bean(destroyMethod="")
public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
bean.setJndiName("java:comp/env/jdbc/myDataSource");
bean.setProxyInterface(DataSource.class);
bean.setLookupOnStartup(false);
bean.afterPropertiesSet();
return (DataSource)bean.getObject();
}
- 3 回答
- 0 关注
- 1351 浏览
添加回答
举报