java - 使用嵌入式容器和 JNDI 运行 Spring Boot 应用程序

标签 java maven spring-boot spring-data jndi

我有一个带有 spring.datasource.jndi-name=java:/foo 属性的 Spring Boot 应用程序,它在 WildFly 下运行良好。

我想使用嵌入式容器运行相同的应用程序,即 mvn spring-boot:run,但是虽然 WildFly 在其配置中配置了 JNDI 数据源,但嵌入式容器没有,即我得到:

org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException:
Failed to look up JNDI DataSource with name 'java:/foo'

我想我必须在某处包含一个 XML 文件来为嵌入式容器配置 JNDI 数据源,但我找不到关于此的文档。我刚刚找到了有关如何在 Java 源代码中创建 JNDI 数据源的教程,但我想避免这种情况,以便同一应用程序可以同时在外部和嵌入式容器中运行。

我怎样才能做到这一点?

编辑 This answer展示了如何在 Tomcat 中以一种会中断在其他容器(例如 WildFly)中运行相同应用程序的方式创建 JNDI 上下文。我正在寻找一个答案,让应用程序在不同的容器中使用相同的源运行,例如只需使用在 WildFly 中配置的相同 JNDI 资源配置嵌入式容器。

最佳答案

要使该应用程序也可部署在其他启用 jndi 的容器中,请执行以下操作;

  1. 扩展 TomcatEmbeddedServletContainerFactory 并启用 jndi 命名并添加资源
  2. 创建一个带有 Profile 注释的配置类,它公开了扩展的 TomcatEmbeddedServletContainerFactory bean

见下面的代码;

扩展 TomcatEmbeddedServletContainerFactory

class EmbeddedServletContainerFactory extends TomcatEmbeddedServletContainerFactory {
    @Override
    protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
        tomcat.enableNaming(); // This is essential. Naming is disabled by default which needs enabling
        return super.getTomcatEmbeddedServletContainer(tomcat);
    }

    @Override
    protected void postProcessContext(Context context) {
        ContextResource resource = new ContextResource();
        // All the below properties you can retrieve via preferred method
        resource.setName("jdbc/test");
        resource.setAuth("Container");
        resource.setType(DataSource.class.getName());
        resource.setProperty("driverClassName", driverClass);
        resource.setProperty("factory", "org.apache.commons.dbcp2.BasicDataSourceFactory");
        resource.setProperty("url", dbUrl);
        resource.setProperty("username", username);
        resource.setProperty("password", password);
        context.getNamingResources().addResource(resource);
    }
}

公开 bean 的配置类

@Profile("embedded")
@Configuration
public class EmbeddedConfig {

    @Bean
    public TomcatEmbeddedServletContainerFactory tomcatFactory() {
        return new EmbeddedServletContainerFactory();
    }
}

如果你不喜欢在 java 配置中这样做,你可以在 xml 中做同样的事情

<beans profile="embedded">
    <bean id="TomcatEmbeddedServletContainerFactory" class="EmbeddedServletContainerFactory" />
</bean>

现在您可以在 pom 中对个人资料名称进行硬编码或者通过 jvm 参数添加它;

mvn spring-boot:run -Drun.profiles=embedded

您的其他代码保持不变,并且在其他容器中的行为也相同。通过 jndi 查找数据源也保持不变。此代码确保实际上有一个数据源绑定(bind)到嵌入式容器中的那个 jndi。

关于java - 使用嵌入式容器和 JNDI 运行 Spring Boot 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48091688/

相关文章:

java - Maven 与 npm 类似吗?

java - 调试 war 文件中特定 jar 文件的包含情况

java - 无法转换到类 org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreaker

java - SpringBoot注入(inject): OK with app,但没有经过测试

java - XJC xs :choice inheritance

java - Exo播放器 : setNotificationListener is deprecated

java - 对 CountedCompleter 的文档和来源感到困惑

java - 在程序中实现 JAVE

java - 在 mac os 上使用 maven 运行 Spring Boot 失败

spring - Null Last 不适用于 spring 数据 jpa