parent
638cbfd595
commit
64d2467891
@ -0,0 +1,35 @@
|
|||||||
|
package au.com.royalpay.payment.manage.pos.datasource;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多数据源配置类
|
||||||
|
* Created by Dulingling on 2019/8/7
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
|
public class DataSourceConfiguration {
|
||||||
|
@Value("${spring.datasource.type}")
|
||||||
|
private Class<? extends DataSource> dataSourceType;
|
||||||
|
|
||||||
|
@Bean(name = "masterDataSource")
|
||||||
|
@Primary
|
||||||
|
@ConfigurationProperties(prefix = "spring.datasource.master")
|
||||||
|
public DataSource masterDataSource(){
|
||||||
|
return DataSourceBuilder.create().type(dataSourceType).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "slaveDataSource")
|
||||||
|
@ConfigurationProperties(prefix = "spring.datasource.slave")
|
||||||
|
public DataSource slaveDataSource1(){
|
||||||
|
return DataSourceBuilder.create().type(dataSourceType).build();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package au.com.royalpay.payment.manage.pos.datasource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Dulingling on 2019/8/7
|
||||||
|
*/
|
||||||
|
public class DbContextHolder {
|
||||||
|
|
||||||
|
public enum DbType{
|
||||||
|
MASTER,SLAVE
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<>();
|
||||||
|
|
||||||
|
public static void setDbType(DbType dbType){
|
||||||
|
if(dbType==null)throw new NullPointerException();
|
||||||
|
contextHolder.set(dbType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DbType getDbType(){
|
||||||
|
DbType dbType = contextHolder.get();
|
||||||
|
return dbType ==null? DbType.MASTER: dbType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearDbType(){
|
||||||
|
contextHolder.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package au.com.royalpay.payment.manage.pos.datasource;
|
||||||
|
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.ibatis.mapping.DatabaseIdProvider;
|
||||||
|
import org.apache.ibatis.plugin.Interceptor;
|
||||||
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
|
import org.aspectj.apache.bcel.util.ClassLoaderRepository;
|
||||||
|
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
|
||||||
|
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
|
||||||
|
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Dulingling on 2019/8/7
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@AutoConfigureAfter({DataSourceConfiguration.class})
|
||||||
|
public class MybatisConfiguration extends MybatisAutoConfiguration {
|
||||||
|
|
||||||
|
|
||||||
|
private static Log logger = LogFactory.getLog(MybatisConfiguration.class);
|
||||||
|
|
||||||
|
@Resource(name = "masterDataSource")
|
||||||
|
private DataSource masterDataSource;
|
||||||
|
@Resource(name = "slaveDataSource")
|
||||||
|
private DataSource slaveDataSource;
|
||||||
|
|
||||||
|
public MybatisConfiguration(MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
|
||||||
|
super(properties, interceptorsProvider, resourceLoader, databaseIdProvider, configurationCustomizersProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SqlSessionFactory sqlSessionFactory() throws Exception {
|
||||||
|
return super.sqlSessionFactory(roundRobinDataSouceProxy());
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractRoutingDataSource roundRobinDataSouceProxy(){
|
||||||
|
ReadWriteSplitRoutingDataSource proxy = new ReadWriteSplitRoutingDataSource();
|
||||||
|
Map<Object,Object> targetDataResources = new ClassLoaderRepository.SoftHashMap();
|
||||||
|
targetDataResources.put(DbContextHolder.DbType.MASTER,masterDataSource);
|
||||||
|
targetDataResources.put(DbContextHolder.DbType.SLAVE,slaveDataSource);
|
||||||
|
proxy.setDefaultTargetDataSource(masterDataSource);//默认源
|
||||||
|
proxy.setTargetDataSources(targetDataResources);
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void test(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
|||||||
|
package au.com.royalpay.payment.manage.pos.datasource;
|
||||||
|
|
||||||
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Around;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Dulingling on 2019/8/7
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class ReadOnlyConnectionInterceptor implements Ordered {
|
||||||
|
|
||||||
|
public static final Logger logger = LoggerFactory.getLogger(ReadOnlyConnectionInterceptor.class);
|
||||||
|
|
||||||
|
@Around("@annotation(readOnlyConnection)")
|
||||||
|
public Object proceed(ProceedingJoinPoint proceedingJoinPoint,ReadOnlyConnection readOnlyConnection) throws Throwable {
|
||||||
|
try {
|
||||||
|
logger.info("set database connection to read only");
|
||||||
|
DbContextHolder.setDbType(DbContextHolder.DbType.SLAVE);
|
||||||
|
Object result = proceedingJoinPoint.proceed();
|
||||||
|
return result;
|
||||||
|
}finally {
|
||||||
|
DbContextHolder.clearDbType();
|
||||||
|
logger.info("restore database connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package au.com.royalpay.payment.manage.pos.datasource;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Dulingling on 2019/8/7
|
||||||
|
*/
|
||||||
|
public class ReadWriteSplitRoutingDataSource extends AbstractRoutingDataSource {
|
||||||
|
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object determineCurrentLookupKey() {
|
||||||
|
DbContextHolder.DbType dataSource = DbContextHolder.getDbType();
|
||||||
|
logger.error("------------------当前数据源:{}---------------------",dataSource);
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue