복붙노트

[SPRING] JNDI로 스프링 부트에서 다중 데이터 소스 설정하기

SPRING

JNDI로 스프링 부트에서 다중 데이터 소스 설정하기

Application Server 내장 기능을 사용하여 여러 DataSource를 관리하고 JNDI를 사용하여 액세스하려고합니다. Spring JPA 데이터로 Spring 부팅을 사용하고 있습니다.

단일 데이터 소스에 대해 application.properties를 구성 할 수 있습니다.

spring.datasource.jndi-name=jdbc/customers

그리고 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"/>

모든 것이 잘 작동합니다.

하지만 두 개의 데이터 소스를 구성 할 수없는 경우

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"/>

나는 application.properties 파일 설정에 대해 의심 스럽다.

아래의 옵션을 사용해 보았는데 성공하지 못했습니다 :

spring.datasource.jndi-name=jdbc/customers,jdbc/employee

여러 데이터 소스에 대해 JNDI가있는 스프링 부트에 대한 자세한 내용을 알려주십시오. 지금 며칠 동안이 구성을 찾고있었습니다.

스프링 부트 설명서에 따른 두 번째 평가판

spring.datasource.primary.jndi-name=jdbc/customer
spring.datasource.secondary.jndi-name=jdbc/project

구성 클래스.

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

응용 프로그램이 시작되지 않습니다. 비록 Tomcat 서버가 시작되고 있습니다. 로그에 오류가 인쇄되지 않습니다.

3 회 시험 : 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

그리고 아래 자바 구성 :

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

하지만 여전히 오류가 발생합니다.

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)

최신 정보: 아래 속성 파일을 사용하여 시험 사용 :

  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

고객 스키마에 모든 테이블을 작성하지만 다른 테이블도 찾으려고하지 않습니다. (두 번째 스키마에서)

해결법

  1. ==============================

    1.이것은 약간 수정 된 세 번째 재판을위한 해결책입니다. 다음 해결책을 고려하십시오 (Spring Boot 1.3.2).

    이것은 약간 수정 된 세 번째 재판을위한 해결책입니다. 다음 해결책을 고려하십시오 (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
    

    구성 :

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

    그런 다음 http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/jpa.repositories.html 안내에 따라 jpa 리포지토리에서 데이터 소스를 사용할 수 있습니다.

  2. ==============================

    2.이를 위해 일반 JndiObjectFactoryBean을 사용할 수 있습니다. DataSourceBuilder를 JndiObjectFactoryBean으로 교체하면됩니다.

    이를 위해 일반 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();
    }
    

    등록 정보

    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
    

    @ConfigurationProperties 주석을 사용하여 JndiObjectFactoryBean의 모든 속성을 설정할 수 있습니다. (필자가 추가 한 예상 유형을 참조하십시오. 그러나 캐시 또는 시작시 검색을 설정할 수도 있습니다.)

    참고 : JNDI 조회를 수행 할 때 destroyMethod를 ""설정하면 응용 프로그램이 종료 될 때 JNDI 자원이 종료 / 종료되는 상황이 발생할 수 있습니다. 이것은 공유 환경에서 원하는 것이 아닙니다.

  3. ==============================

    3.그것은 나를 위해 작동하며 적은 코드가 포함되어 있습니다.

    그것은 나를 위해 작동하며 적은 코드가 포함되어 있습니다.

    @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);
        }
    }
    
  4. from https://stackoverflow.com/questions/32776410/configure-multiple-datasource-in-spring-boot-with-jndi by cc-by-sa and MIT license