Spring Boot 다 중 데이터 원본
위의 글 은 자바 코드 를 손 으로 사용 하여 대상 을 Spring 에 등록 하 는 방법 을 소개 하여 본 고의 '다 중 데이터 소스' 에 기반 을 다 져 주 었 다.
다음 자바 클래스 는 제 가 이미 작성 한 프로필 의 동적 에 따라 다 중 데이터 소스 를 만 드 는 코드 입 니 다. 그 원리 도 간단 합 니 다. 바로 프로필 을 읽 는 것 입 니 다. 프로필 에 설 정 된 데이터 소스 수량 에 따라 동적 으로 데이터 소스 를 만 들 고 Spring 에 등록 하 는 것 입 니 다.코드 는 다음 과 같 습 니 다:
package org.springboot.sample.config;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.AnnotationScopeMetadataResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopeMetadataResolver;
import org.springframework.core.env.Environment;
/**
* Spring
*
* @author (365384722)
* @myblog http://blog.csdn.net/catoop/
* @create 2016 1 22
*/
@Configuration
public class MultipleDataSourceBeanDefinitionRegistryPostProcessor
implements BeanDefinitionRegistryPostProcessor, EnvironmentAware {
private static final Logger logger = LoggerFactory
.getLogger(MultipleDataSourceBeanDefinitionRegistryPostProcessor.class);
// ,
private static final Object DATASOURCE_TYPE_DEFAULT = "org.apache.tomcat.jdbc.pool.DataSource";
// private static final Object DATASOURCE_TYPE_DEFAULT = "com.zaxxer.hikari.HikariDataSource";
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
// DataSource ,
private Map> dataSourceMap = new HashMap<>();
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
logger.info("Invoke Metho postProcessBeanFactory");
beanFactory.getBeanDefinition("dataSource").setPrimary(true);
BeanDefinition bd = null;
Map dsMap = null;
for (Entry> entry : dataSourceMap.entrySet()) {
bd = beanFactory.getBeanDefinition(entry.getKey());
MutablePropertyValues mpv = bd.getPropertyValues();
dsMap = entry.getValue();
mpv.addPropertyValue("driverClassName", dsMap.get("url"));
mpv.addPropertyValue("url", dsMap.get("url"));
mpv.addPropertyValue("username", dsMap.get("username"));
mpv.addPropertyValue("password", dsMap.get("password"));
}
}
@SuppressWarnings("unchecked")
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
logger.info("Invoke Metho postProcessBeanDefinitionRegistry");
try {
if(!dataSourceMap.isEmpty()){
for (Entry> entry : dataSourceMap.entrySet()) {
Object type = entry.getValue().get("type");
if(type == null)
type = DATASOURCE_TYPE_DEFAULT;// DataSource
registerBean(registry, entry.getKey(), (Class extends DataSource>)Class.forName(type.toString()));
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* Bean Spring
*
* @param registry
* @param name
* @param beanClass
* @author SHANHY
* @create 2016 1 22
*/
private void registerBean(BeanDefinitionRegistry registry, String name, Class> beanClass) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// name
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
/**
*
*/
@Override
public void setEnvironment(Environment env) {
RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, "custom.datasource.");
String dsPrefixs = propertyResolver.getProperty("names");
for (String dsPrefix : dsPrefixs.split(",")) {//
Map dsMap = propertyResolver.getSubProperties(dsPrefix + ".");
dataSourceMap.put(dsPrefix, dsMap);
}
}
}
이 자바 파일 을 프로젝트 에 직접 추가 하면 됩 니 다. 다른 코드 결합 없 이 단순 한 클래스 입 니 다.
프로필 에 다 중 데이터 원본 을 설정 하 는 방법 을 다시 봅 시다.
# ,
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
#
custom.datasource.names=ds1,ds2,ds3
custom.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
custom.datasource.ds1.url=jdbc:mysql://localhost:3306/test
custom.datasource.ds1.username=root
custom.datasource.ds1.password=123456
custom.datasource.ds2.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.ds2.driver-class-name=com.mysql.jdbc.Driver
custom.datasource.ds2.url=jdbc:mysql://localhost:3306/test
custom.datasource.ds2.username=root
custom.datasource.ds2.password=123456
custom.datasource.ds3.type=com.zaxxer.hikari.HikariDataSource
custom.datasource.ds3.driver-class-name=com.mysql.jdbc.Driver
custom.datasource.ds3.url=jdbc:mysql://localhost:3306/test
custom.datasource.ds3.username=root
custom.datasource.ds3.password=123456
# ,
spring.datasource.maximum-pool-size=100
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
spring.datasource.validation-query=SELECT 1
spring.datasource.test-on-borrow=false
spring.datasource.test-while-idle=true
spring.datasource.time-between-eviction-runs-millis=18800
설정 파일 은 주 데이터 원본 1 개 와 여러 데이터 원본 을 포함 합 니 다. 그 중에서 주 데이터 원본 이 Spring 에 있 는 beanName 은 기본적으로 dataSource 이 고 다른 몇 개의 데이터 원본 의 beanName 은 ds1, ds2, ds3 로 나 뉘 어 있 습 니 다. 설정 규칙 을 보 세 요. 더 이상 말 할 필요 가 없습니다.그 중에서 datasource 의 type 속성 은 우리 가 필요 로 하 는 데이터 원본 에 구체 적 으로 지정 할 수 있 습 니 다. 지정 하지 않 은 상황 에서 기본 값 은 org. apache. tomcat. jdbc. pool. dataSource 입 니 다.
물론 이 데이터 원본 을 주 dataSource 데이터베이스 에 설정 한 다음 데이터 베 이 스 를 읽 어 다 중 데이터 원본 을 만 들 수도 있 습 니 다.물론 이렇게 하 는 필요 성 은 크 지 않 습 니 다. 데이터 소스 가 자주 변 할 수 있 습 니까?
dataSource 를 사용 할 곳 에 이름 을 지정 해 야 합 니 다. 예 를 들 어:
//
public void testDataSource(@Qualifier("ds1") DataSource myDataSource, @Qualifier("dataSource") DataSource dataSource) {
}
혹은
//
@Autowired
@Qualifier("ds1")
private DataSource dataSource1;
@Resource(name = "ds2")
private DataSource dataSource2;
본 논문 에서 공유 한 코드 는 직접 사용 할 수 있 고 여러분 은 자신의 수요 에 따라 조정 할 수 있 습 니 다.
그러나 우 리 는 프로젝트 에서 반드시 dataSource 를 직접 사용 해 야 하 는 것 이 아 닙 니 다. 모두 JDBC 의 jdbc Template, Mybatis 의 sqlSessionTemplate, 또는 Mybatis 를 예 로 들 어 Mapper 인터페이스 에 직접 동적 대 리 를 하 는 것 에 익숙 합 니 다.
그러면 어떻게 완전 동적 데이터 소스 를 실현 할 수 있 습 니까? 그래서 우 리 는 같은 자바 류 의 서로 다른 방법 으로 서로 다른 데이터 소스 를 사용 할 수 있 습 니까?다음 글 은 모두 에 게 발표 할 것 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.