当前位置: 代码迷 >> java >> Spring应用程序侦听器-ContextRefreshedEvent java:comp / env / jdbc / db未找到
  详细解决方案

Spring应用程序侦听器-ContextRefreshedEvent java:comp / env / jdbc / db未找到

热度:19   发布时间:2023-07-31 11:48:17.0

我正在尝试在应用程序首次启动时进行一些数据库清理。 首先,我将JNDI连接定义如下:

@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);
        }
    };
}

然后我希望在ApplicationListener ContextRefreshedEvent中检索资源,ApplicationListener实现如下:

@Component
public class StartupConfiguration implements ApplicationListener<ContextRefreshedEvent>
{
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event)
    {
        ApplicationContext ctx = event.getApplicationContext();

        Context initialContext = new InitialContext();
        DataSource datasource = (DataSource) initialContext.lookup("java:comp/env/jdbc/myDataSource");
        ...
    }

}

问题是它无法找到java:comp / env / jdbc / myDataSource,我已经使用各种事件进行了测试,而唯一起作用的事件是RequestHandledEvent ,我认为这不是一个很好的解决方案。

我在以下堆栈溢出问题中找到了答案stackoverflow.com/questions/27822619

我会引用安迪·威尔金森(Andy Wilkinson)

Tomcat使用线程的上下文类加载器确定要执行查找的JNDI上下文。 如果线程上下文类加载器不是Web应用程序类加载器,则JNDI上下文为空,因此查找失败。

还有安迪·威尔金森(Andy Wilkinson)提出的修复建议

@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {

    @Override
    protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
            Tomcat tomcat) {
        tomcat.enableNaming();
        TomcatEmbeddedServletContainer container = 
                super.getTomcatEmbeddedServletContainer(tomcat);
        for (Container child: container.getTomcat().getHost().findChildren()) {
            if (child instanceof Context) {
                ClassLoader contextClassLoader = 
                        ((Context)child).getLoader().getClassLoader();
                Thread.currentThread().setContextClassLoader(contextClassLoader);
                break;
            }
        }
        return container;
    }

    @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);
    }
};
}
  相关解决方案