Commit d87ee3b784cea3d6d9477eebe60a812bf4ddb0ab

Authored by huanggang
1 parent f16598b4

multiple data source supported

boss-boot/src/main/java/com/diligrp/boss/boot/controller/BossOpenApiController.java
1 1 package com.diligrp.boss.boot.controller;
2 2  
  3 +import com.diligrp.boss.shared.datasource.DataSourceOption;
  4 +import com.diligrp.boss.shared.datasource.DataSourceName;
3 5 import com.diligrp.boss.shared.domain.Message;
4 6 import com.diligrp.boss.shared.uid.KeyGenerator;
5 7 import com.diligrp.boss.shared.uid.KeyGeneratorManager;
... ... @@ -13,7 +15,8 @@ public class BossOpenApiController {
13 15 @Resource
14 16 private KeyGeneratorManager keyGeneratorManager;
15 17  
16   - @RequestMapping(value = "/uid/get.do")
  18 + @RequestMapping("/uid/get.do")
  19 + @DataSourceOption(DataSourceName.MASTER)
17 20 public Message<?> testUid() {
18 21 KeyGenerator keyGenerator = keyGeneratorManager.getKeyGenerator("TEST_KEY");
19 22 return Message.success(keyGenerator.nextId());
... ...
boss-boot/src/main/resources/application-dev.properties
... ... @@ -12,6 +12,19 @@ spring.datasource.hikari.max-lifetime=900000
12 12 spring.datasource.hikari.connection-timeout=15000
13 13 spring.datasource.hikari.connection-test-query=SELECT 1
14 14  
  15 +spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
  16 +spring.datasource.slave.url=jdbc:mysql://mysql.diligrp.com:3306/dili_assistant?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=GMT%2B8
  17 +spring.datasource.slave.username=root
  18 +spring.datasource.slave.password=123456
  19 +spring.datasource.slave.type=com.zaxxer.hikari.HikariDataSource
  20 +spring.datasource.slave.hikari.pool-name=SlaveHikariPool
  21 +spring.datasource.slave.hikari.minimum-idle=4
  22 +spring.datasource.slave.hikari.maximum-pool-size=60
  23 +spring.datasource.slave.hikari.idle-timeout=120000
  24 +spring.datasource.slave.hikari.max-lifetime=900000
  25 +spring.datasource.slave.hikari.connection-timeout=15000
  26 +spring.datasource.slave.hikari.connection-test-query=SELECT 1
  27 +
15 28 #Redis configuration
16 29 spring.data.redis.host=redis.diligrp.com
17 30 spring.data.redis.port=6379
... ...
boss-boot/src/main/resources/application-prod.properties
... ... @@ -12,6 +12,19 @@ spring.datasource.hikari.max-lifetime=900000
12 12 spring.datasource.hikari.connection-timeout=15000
13 13 spring.datasource.hikari.connection-test-query=SELECT 1
14 14  
  15 +spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
  16 +spring.datasource.slave.url=jdbc:mysql://mysql.diligrp.com:3306/dili_assistant?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=GMT%2B8
  17 +spring.datasource.slave.username=root
  18 +spring.datasource.slave.password=123456
  19 +spring.datasource.slave.type=com.zaxxer.hikari.HikariDataSource
  20 +spring.datasource.slave.hikari.pool-name=SlaveHikariPool
  21 +spring.datasource.slave.hikari.minimum-idle=4
  22 +spring.datasource.slave.hikari.maximum-pool-size=60
  23 +spring.datasource.slave.hikari.idle-timeout=120000
  24 +spring.datasource.slave.hikari.max-lifetime=900000
  25 +spring.datasource.slave.hikari.connection-timeout=15000
  26 +spring.datasource.slave.hikari.connection-test-query=SELECT 1
  27 +
15 28 #Redis configuration
16 29 spring.data.redis.host=redis.diligrp.com
17 30 spring.data.redis.port=6379
... ...
boss-boot/src/main/resources/application-test.properties
... ... @@ -12,6 +12,19 @@ spring.datasource.hikari.max-lifetime=900000
12 12 spring.datasource.hikari.connection-timeout=15000
13 13 spring.datasource.hikari.connection-test-query=SELECT 1
14 14  
  15 +spring.datasource.slave.driver-class-name=com.mysql.cj.jdbc.Driver
  16 +spring.datasource.slave.url=jdbc:mysql://mysql.diligrp.com:3306/dili_assistant?useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&serverTimezone=GMT%2B8
  17 +spring.datasource.slave.username=root
  18 +spring.datasource.slave.password=123456
  19 +spring.datasource.slave.type=com.zaxxer.hikari.HikariDataSource
  20 +spring.datasource.slave.hikari.pool-name=SlaveHikariPool
  21 +spring.datasource.slave.hikari.minimum-idle=4
  22 +spring.datasource.slave.hikari.maximum-pool-size=60
  23 +spring.datasource.slave.hikari.idle-timeout=120000
  24 +spring.datasource.slave.hikari.max-lifetime=900000
  25 +spring.datasource.slave.hikari.connection-timeout=15000
  26 +spring.datasource.slave.hikari.connection-test-query=SELECT 1
  27 +
15 28 #Redis configuration
16 29 spring.data.redis.host=redis.diligrp.com
17 30 spring.data.redis.port=6379
... ...
boss-shared/src/main/java/com/diligrp/boss/shared/datasource/DataSourceConfiguration.java 0 → 100644
  1 +package com.diligrp.boss.shared.datasource;
  2 +
  3 +import com.zaxxer.hikari.HikariDataSource;
  4 +import org.aspectj.lang.ProceedingJoinPoint;
  5 +import org.aspectj.lang.annotation.Around;
  6 +import org.aspectj.lang.annotation.Aspect;
  7 +import org.aspectj.lang.annotation.Pointcut;
  8 +import org.aspectj.lang.reflect.MethodSignature;
  9 +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
  10 +import org.springframework.boot.context.properties.ConfigurationProperties;
  11 +import org.springframework.context.annotation.Bean;
  12 +import org.springframework.context.annotation.Configuration;
  13 +import org.springframework.context.annotation.Primary;
  14 +
  15 +import javax.sql.DataSource;
  16 +import java.util.HashMap;
  17 +import java.util.Map;
  18 +import java.util.Objects;
  19 +
  20 +@Aspect
  21 +@Configuration
  22 +public class DataSourceConfiguration {
  23 +
  24 + @Bean
  25 + @ConfigurationProperties(prefix = "spring.datasource")
  26 + public DataSourceProperties masterProperties() {
  27 + return new DataSourceProperties();
  28 + }
  29 +
  30 + @Bean
  31 + @ConfigurationProperties(prefix = "spring.datasource.hikari")
  32 + public DataSource masterDataSource() {
  33 + HikariDataSource dataSource = new HikariDataSource();
  34 + DataSourceProperties properties = masterProperties();
  35 + dataSource.setDriverClassName(properties.determineDriverClassName());
  36 + dataSource.setJdbcUrl(properties.determineUrl());
  37 + dataSource.setUsername(properties.determineUsername());
  38 + dataSource.setPassword(properties.determinePassword());
  39 + return dataSource;
  40 + }
  41 +
  42 + @Bean
  43 + @ConfigurationProperties(prefix = "spring.datasource.slave")
  44 + public DataSourceProperties slaveProperties() {
  45 + return new DataSourceProperties();
  46 + }
  47 +
  48 + @Bean
  49 + @ConfigurationProperties(prefix = "spring.datasource.slave.hikari")
  50 + public DataSource salveDataSource() {
  51 + HikariDataSource dataSource = new HikariDataSource();
  52 + DataSourceProperties properties = slaveProperties();
  53 + dataSource.setDriverClassName(properties.determineDriverClassName());
  54 + dataSource.setJdbcUrl(properties.determineUrl());
  55 + dataSource.setUsername(properties.determineUsername());
  56 + dataSource.setPassword(properties.determinePassword());
  57 + return dataSource;
  58 + }
  59 +
  60 + @Bean
  61 + @Primary
  62 + public DataSource dynamicDataSource() {
  63 + Map<Object, Object> datasourceMap = new HashMap<>();
  64 + datasourceMap.put(DataSourceName.MASTER, masterDataSource());
  65 + datasourceMap.put(DataSourceName.SLAVE, salveDataSource());
  66 +
  67 + MultipleDataSource multipleDataSource = new MultipleDataSource();
  68 + multipleDataSource.setTargetDataSources(datasourceMap);
  69 + multipleDataSource.setDefaultTargetDataSource(masterDataSource());
  70 + return multipleDataSource;
  71 + }
  72 +
  73 + @Pointcut(value = "@annotation(com.diligrp.boss.shared.datasource.DataSourceOption)")
  74 + public void dataSourcePointCut(){
  75 + }
  76 +
  77 + @Around("dataSourcePointCut()")
  78 + public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
  79 + DataSourceName name = getMetadata(joinPoint).value();
  80 + try{
  81 + DataSourceNameContext.setDataSourceName(name);
  82 + return joinPoint.proceed();
  83 + }finally {
  84 + DataSourceNameContext.removeDataSourceName();
  85 + }
  86 + }
  87 +
  88 + private DataSourceOption getMetadata(ProceedingJoinPoint joinPoint) {
  89 + Class<?> targetClass = joinPoint.getTarget().getClass();
  90 + DataSourceOption annotation = targetClass.getAnnotation(DataSourceOption.class);
  91 + if (Objects.nonNull(annotation)) {
  92 + return annotation;
  93 + } else {
  94 + MethodSignature signature = (MethodSignature) joinPoint.getSignature();
  95 + return signature.getMethod().getAnnotation(DataSourceOption.class);
  96 + }
  97 + }
  98 +}
... ...
boss-shared/src/main/java/com/diligrp/boss/shared/datasource/DataSourceName.java 0 → 100644
  1 +package com.diligrp.boss.shared.datasource;
  2 +
  3 +public enum DataSourceName {
  4 + MASTER,
  5 +
  6 + SLAVE;
  7 +}
... ...
boss-shared/src/main/java/com/diligrp/boss/shared/datasource/DataSourceNameContext.java 0 → 100644
  1 +package com.diligrp.boss.shared.datasource;
  2 +
  3 +public class DataSourceNameContext {
  4 + private static final ThreadLocal<DataSourceName> CONTEXT = new ThreadLocal<>();
  5 +
  6 + public static void setDataSourceName(DataSourceName name){
  7 + CONTEXT.set(name);
  8 + }
  9 +
  10 + public static DataSourceName getDataSourceName() {
  11 + DataSourceName name = CONTEXT.get();
  12 + return name != null ? name : DataSourceName.MASTER;
  13 + }
  14 +
  15 + public static void removeDataSourceName() {
  16 + CONTEXT.remove();
  17 + }
  18 +}
... ...
boss-shared/src/main/java/com/diligrp/boss/shared/datasource/DataSourceOption.java 0 → 100644
  1 +package com.diligrp.boss.shared.datasource;
  2 +
  3 +import java.lang.annotation.ElementType;
  4 +import java.lang.annotation.Retention;
  5 +import java.lang.annotation.RetentionPolicy;
  6 +import java.lang.annotation.Target;
  7 +
  8 +@Retention(RetentionPolicy.RUNTIME)
  9 +@Target({ElementType.METHOD})
  10 +public @interface DataSourceOption {
  11 + DataSourceName value() default DataSourceName.MASTER;
  12 +}
... ...
boss-shared/src/main/java/com/diligrp/boss/shared/datasource/MultipleDataSource.java 0 → 100644
  1 +package com.diligrp.boss.shared.datasource;
  2 +
  3 +import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
  4 +
  5 +public class MultipleDataSource extends AbstractRoutingDataSource {
  6 + @Override
  7 + protected Object determineCurrentLookupKey() {
  8 + return DataSourceNameContext.getDataSourceName();
  9 + }
  10 +}
... ...