使用JNDI在Spring Boot中配置多个DataSource

Man*_*anu 8 java spring jndi spring-data spring-boot

我要管理多发使用您的应用程序服务器的内置功能DataSource和使用JNDI访问它.我使用Spring JPA数据进行Spring启动.

我能够为单个数据源配置application.properties: -

spring.datasource.jndi-name=jdbc/customers
Run Code Online (Sandbox Code Playgroud)

我在context.xml文件中的配置如下: -

<Resource name="jdbc/customer" auth="Container" type="javax.sql.DataSource"
               maxTotal="100" maxIdle="30" maxWaitMillis="10000"
               username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/customer"/>
Run Code Online (Sandbox Code Playgroud)

一切正常.

但是当我无法配置两个数据源时.

我确定在context.xml文件中的配置: -

 <Resource name="jdbc/customer" auth="Container" type="javax.sql.DataSource"
                   maxTotal="100" maxIdle="30" maxWaitMillis="10000"
                   username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/customer"/>

 <Resource name="jdbc/employee" auth="Container" type="javax.sql.DataSource"
                   maxTotal="100" maxIdle="30" maxWaitMillis="10000"
                   username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/employee"/>
Run Code Online (Sandbox Code Playgroud)

我对application.properties文件配置有疑问.

我尝试了以下选项但没有成功: -

spring.datasource.jndi-name=jdbc/customers,jdbc/employee
Run Code Online (Sandbox Code Playgroud)

有关多个数据源的JNDI,请告诉我有关Spring启动的任何详细信息.我好几天都在寻找这种配置.任何形式的建议或评论都会受到高度赞赏.

根据Spring Boot文档进行第二次试验

spring.datasource.primary.jndi-name=jdbc/customer
spring.datasource.secondary.jndi-name=jdbc/project
Run Code Online (Sandbox Code Playgroud)

配置类.

@Bean
@Primary
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
    return DataSourceBuilder.create().build();
}
Run Code Online (Sandbox Code Playgroud)

该应用程序无法启动.虽然tomcat服务器正在启动.日志中不会打印错误.

第三次试验: - 使用JndiObjectFactoryBean

我有以下application.properties

spring.datasource.primary.expected-type=javax.sql.DataSource
spring.datasource.primary.jndi-name=jdbc/customer
spring.datasource.primary.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.datasource.primary.jpa.show-sql=false
spring.datasource.primary.jpa.hibernate.ddl-auto=validate

spring.datasource.secondary.jndi-name=jdbc/employee
spring.datasource.secondary.expected-type=javax.sql.DataSource
spring.datasource.secondary.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.datasource.secondary.jpa.show-sql=false
spring.datasource.secondary.jpa.hibernate.ddl-auto=validate
Run Code Online (Sandbox Code Playgroud)

以下java配置: -

@Bean(destroyMethod="")
@Primary
@ConfigurationProperties(prefix="spring.datasource.primary")
public FactoryBean primaryDataSource() {
    return new JndiObjectFactoryBean();
}

@Bean(destroyMethod="")
@ConfigurationProperties(prefix="spring.datasource.secondary")
public FactoryBean secondaryDataSource() {
    return new JndiObjectFactoryBean();
}
Run Code Online (Sandbox Code Playgroud)

但仍然得到错误: -

Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'primaryDataSource' defined in class path resource [com/web/initializer/MvcConfig.class]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [jdbc/customer] is not bound in this Context. Unable to find [jdbc].
Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'secondaryDataSource' defined in class path resource [com/web/initializer/MvcConfig.class]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [jdbc/employee] is not bound in this Context. Unable to find [jdbc].
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
        at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:117)
        at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:108)
        at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:68)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
Run Code Online (Sandbox Code Playgroud)

更新: - 使用以下属性文件进行试用: -

  spring.datasource.primary.expected-type=javax.sql.DataSource
   spring.datasource.primary.jndi-name=java:comp/env/jdbc/customer

   spring.datasource.secondary.jndi-name=java:comp/env/jdbc/employee
   spring.datasource.secondary.expected-type=javax.sql.DataSource

   spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
   spring.jpa.show-sql=false
   spring.jpa.hibernate.ddl-auto=validate
Run Code Online (Sandbox Code Playgroud)

它会在客户架构中创建所有表,但也无法尝试查找其他表.(来自第二个架构)

And*_*rul 7

这是您的第三次试验的解决方案稍作修改.考虑这个解决方案(Spring Boot 1.3.2):

application.properties文件:

spring.datasource.primary.jndi-name=java:/comp/env/jdbc/SecurityDS
spring.datasource.primary.driver-class-name=org.postgresql.Driver

spring.datasource.secondary.jndi-name=java:/comp/env/jdbc/TmsDS
spring.datasource.secondary.driver-class-name=org.postgresql.Driver

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
spring.jpa.show-sql=false
Run Code Online (Sandbox Code Playgroud)

组态:

@Configuration@ EnableConfigurationProperties
public class AppConfig {

    @Bean@ ConfigurationProperties(prefix = "spring.datasource.primary")
    public JndiPropertyHolder primary() {
        return new JndiPropertyHolder();
    }

    @Bean@ Primary
    public DataSource primaryDataSource() {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = dataSourceLookup.getDataSource(primary().getJndiName());
        return dataSource;
    }

    @Bean@ ConfigurationProperties(prefix = "spring.datasource.secondary")
    public JndiPropertyHolder secondary() {
        return new JndiPropertyHolder();
    }

    @Bean
    public DataSource secondaryDataSource() {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        DataSource dataSource = dataSourceLookup.getDataSource(secondary().getJndiName());
        return dataSource;
    }

    private static class JndiPropertyHolder {
        private String jndiName;

        public String getJndiName() {
            return jndiName;
        }

        public void setJndiName(String jndiName) {
            this.jndiName = jndiName;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以按照指南http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/jpa.repositories.html将您的数据源与jpa存储库一起使用.


And*_*nyk 6

它对我有用并且包含更少的代码

@Configuration
public class Config {
    @Value("${spring.datasource.primary.jndi-name}")
    private String primaryJndiName;

    @Value("${spring.datasource.secondary.jndi-name}")
    private String secondaryJndiName;

    private JndiDataSourceLookup lookup = new JndiDataSourceLookup();

    @Primary
    @Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability
    public DataSource primaryDs() {
        return lookup.getDataSource(primaryJndiName);
    }

    @Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability
    public DataSource secondaryDs() {
        return lookup.getDataSource(secondaryJndiName);
    }
}
Run Code Online (Sandbox Code Playgroud)


M. *_*num 5

你可以使用平原JndiObjectFactoryBean.只需更换DataSourceBuilder一个JndiObjectFactoryBean应该做的伎俩.

Java配置

@Bean(destroyMethod="")
@Primary
@ConfigurationProperties(prefix="datasource.primary")
public FactoryBean primaryDataSource() {
    return new JndiObjectFactoryBean();
}

@Bean(destroyMethod="")
@ConfigurationProperties(prefix="datasource.secondary")
public FactoryBean secondaryDataSource() {
    return new JndiObjectFactoryBean();
}
Run Code Online (Sandbox Code Playgroud)

属性

datasource.primary.jndi-name=jdbc/customer
datasource.primary.expected-type=javax.sql.DataSource
datasource.secondary.jndi-name=jdbc/project
datasource.secondary.expected-type=javax.sql.DataSource
Run Code Online (Sandbox Code Playgroud)

您可以JndiObjectFactoryBean使用@ConfigurationProperties注释设置每个属性.(见expected-type我加了,但你也可以设置cachelookup-on-startup等).

注意:在执行JNDI查找时设置destroyMethod""else,您可能会遇到这样的情况:当应用程序关闭时,您的JNDI资源也会被关闭/关闭.在共享环境中,这不是您想要的.