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 關注
- 1410 瀏覽
添加回答
舉報