Commit d2847177 by 陈文顺

多数据源 ;apollo接入

parent b839c437
package com.freemud.demo.dto;
/**
* Created by chenwenshun on 2018/12/12.
*/
public class BaseRequest {
private String companyId;
public String getCompanyId() {
return companyId;
}
public void setCompanyId(String companyId) {
this.companyId = companyId;
}
}
......@@ -4,7 +4,7 @@ package com.freemud.demo.dto;
* Created by chenwenshun on 2018/11/2.
*/
public class PageReq {
public class PageReq extends BaseRequest{
/**
* 页码
*/
......
......@@ -40,6 +40,10 @@ public class DictTypeServiceImpl implements IDictTypeService{
@Autowired
DictRedisHashCache dictRedisHashCache;
public void setDictRedisHashCache(DictRedisHashCache dictRedisHashCache) {
this.dictRedisHashCache = dictRedisHashCache;
}
@Override
public TDictType loadDictById(long dictTypeId) {
return null;
......@@ -213,6 +217,9 @@ public class DictTypeServiceImpl implements IDictTypeService{
// }
Map<String,DictDataDto> map = dictRedisHashCache.getAllValue(dictTypeCd);
if (map == null){
return dictDataDtos;
}
dictDataDtos = new ArrayList<>(map.values());
dictDataDtos = dictDataDtos.stream()
......
......@@ -74,18 +74,18 @@
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-eureka</artifactId>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-starter-actuator</artifactId>-->
<!--</dependency>-->
<!--<dependency>-->
<!--<groupId>org.springframework.cloud</groupId>-->
<!--<artifactId>spring-cloud-starter-feign</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
......@@ -128,6 +128,12 @@
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
......
......@@ -4,7 +4,6 @@ import com.alibaba.fastjson.support.spring.FastJsonpHttpMessageConverter4;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.converter.HttpMessageConverter;
......@@ -12,7 +11,7 @@ import org.springframework.http.converter.HttpMessageConverter;
@SpringBootApplication
@ComponentScan(basePackages = "com.freemud, cn.freemud")
@MapperScan(basePackages = "com.freemud.demo.mapper")
@EnableEurekaClient
//@EnableEurekaClient
public class SpringbootDemoApplication {
public static void main(String[] args) {
......@@ -23,4 +22,6 @@ public class SpringbootDemoApplication {
public HttpMessageConverter getConverter(){
return new FastJsonpHttpMessageConverter4();
}
}
package com.freemud.springbootdemo.aspect;
import com.freemud.demo.dto.BaseRequest;
import com.freemud.springbootdemo.config.DataSourceEnum;
import com.freemud.springbootdemo.config.DataSourceMapping;
import com.freemud.springbootdemo.config.RoutingDataSourceContextHolder;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.javassist.*;
import org.apache.ibatis.javassist.bytecode.CodeAttribute;
import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute;
import org.apache.ibatis.javassist.bytecode.MethodInfo;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created by chenwenshun on 2018/12/12.
*/
@Aspect
@Component
public class RoutingDataSourceAspect {
@Autowired
private DataSourceMapping dataSourceMapping;
@Pointcut("execution(public * com.freemud.springbootdemo.controller.*.*(..))")
public void point() {
}
@Before("point()")
public void doBefore(JoinPoint joinPoint) throws ClassNotFoundException, NotFoundException {
String classType = joinPoint.getTarget().getClass().getName();
// Class<?> clazz = Class.forName(classType);
// String clazzName = clazz.getName();
String methodName = joinPoint.getSignature().getName(); //获取方法名称
Object[] args = joinPoint.getArgs();//参数
Map<String,Object> nameAndArgs = this.getFieldsName(this.getClass(),classType,methodName,args);
String companyId = null;
if (nameAndArgs.containsKey("companyId")){
companyId = (String)nameAndArgs.get("companyId");
}else if (nameAndArgs.containsKey("requestBody")){
BaseRequest request = (BaseRequest)nameAndArgs.get("requestBody");
companyId = request.getCompanyId();
}else {
BaseRequest request = (BaseRequest)Lists.newArrayList(nameAndArgs.values()).get(0);
companyId = request.getCompanyId();
}
if (StringUtils.isBlank(companyId)){
throw new UnsupportedOperationException("companyId can not be null!");
}
String ds = DataSourceEnum.DS_1.name();
if (dataSourceMapping != null){
ds = dataSourceMapping.getDataSource(Lists.newArrayList(DataSourceEnum.values()) ,"datasource_company_map_"+ companyId) ;
}
RoutingDataSourceContextHolder.set(DataSourceEnum.valueOf(ds));
}
@After("point()")
public void doAfter(){
RoutingDataSourceContextHolder.clear();
}
private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName, Object[] args) throws NotFoundException {
Map<String,Object > map=new LinkedHashMap<>();
ClassPool pool = ClassPool.getDefault();
ClassClassPath classPath = new ClassClassPath(cls);
pool.insertClassPath(classPath);
CtClass cc = pool.get(clazzName);
CtMethod cm = cc.getDeclaredMethod(methodName);
MethodInfo methodInfo = cm.getMethodInfo();
CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
for (int i = 0; i < cm.getParameterTypes().length; i++){
map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名
}
return map;
}
}
package com.freemud.springbootdemo.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
......@@ -8,6 +10,9 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* Created by chenwenshun on 2018/8/31.
......@@ -17,20 +22,37 @@ public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "datasource.druid")
@Primary
public DataSource dataSource(){
public DataSource dataSource1(){
return DataSourceBuilder.create()
.type(DruidDataSource.class)
.build();
}
@Bean
@ConfigurationProperties(prefix = "datasource2.druid")
public DataSource dataSource2(){
return DataSourceBuilder.create()
.type(DruidDataSource.class)
.build();
}
// @Bean
// @ConfigurationProperties(prefix = "datasource2.druid")
// public DataSource dataSource2(){
// return DataSourceBuilder.create()
// .type(DruidDataSource.class)
// .build();
// }
@Bean
@Primary
public DataSource RoutingDataSource(
@Autowired @Qualifier("dataSource1") DataSource dataSource,
@Autowired @Qualifier("dataSource2") DataSource dataSource2
){
Map<Object, Object> map = new HashMap<>();
map.put(DataSourceEnum.DS_1, dataSource);
map.put(DataSourceEnum.DS_2, dataSource2);
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setTargetDataSources(map);
routingDataSource.setDefaultTargetDataSource(dataSource);
return routingDataSource;
}
}
package com.freemud.springbootdemo.config;
/**
* Created by chenwenshun on 2018/12/14.
* 多数据源编号
*/
public enum DataSourceEnum {
DS_1,
DS_2
}
package com.freemud.springbootdemo.config;
import java.util.Collection;
import java.util.List;
/**
* Created by chenwenshun on 2018/12/14.
* 商户与数据源的映射关系
* 具体项目不用实现
* 如:用数据库配置或者apollo,等方式
*/
public interface DataSourceMapping {
/**
* 商户ID 返回对应的数据源,可以采取两种方式
*
* 1、通过具体的配置
*
* 2、通过自己实现路由算法返回对应的数据源
* @param availableDataSources
* @param companyId
* @return
*/
String getDataSource(List<DataSourceEnum> availableDataSources, String companyId);
}
package com.freemud.springbootdemo.config;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
/**
* Created by chenwenshun on 2018/12/14.
*/
@Component
public class DataSourceMappingImpl implements DataSourceMapping {
@ApolloConfig
private Config config;
@Override
public String getDataSource(List<DataSourceEnum> availableDataSources, String companyId) {
return config.getProperty(companyId, DataSourceEnum.DS_1.name());
}
}
package com.freemud.springbootdemo.config;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* Created by chenwenshun on 2018/12/12.
*/
public class RoutingDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
return RoutingDataSourceContextHolder.get();
}
}
package com.freemud.springbootdemo.config;
/**
* Created by chenwenshun on 2018/12/12.
*/
public class RoutingDataSourceContextHolder {
private static final ThreadLocal<DataSourceEnum> threadlocalDataSourceKey = new ThreadLocal<>();
public static void set(DataSourceEnum key){
threadlocalDataSourceKey.set(key);
}
public static DataSourceEnum get(){
return threadlocalDataSourceKey.get();
}
public static void clear() {
threadlocalDataSourceKey.remove();
}
}
......@@ -68,7 +68,7 @@ public class DictController {
@GetMapping("/delete")
public ResDto delete(Long dictTypeId){
public ResDto delete(Long dictTypeId,String companyId){
this.dictTypeService.deleteDict(dictTypeId);
return new ResDto();
}
......
......@@ -6,6 +6,8 @@ spring:
port: 5289
password: U252fnIDyfF1A1
database: 3
datasource:
initialize: false
server:
port: 9005
datasource:
......@@ -20,6 +22,17 @@ datasource:
test-on-borrow: true
filters: stat
datasource2:
druid:
url: jdbc:mysql://111.231.82.13:6630/dict?useUnicode=true&characterEncoding=utf8
driver-class: com.mysql.jdbc.Driver
username: yanfa
password: yqKjKHX.1:bv
initial-size: 1
min-idle: 1
max-active: 20
test-on-borrow: true
filters: stat
#mybatis
......@@ -54,9 +67,18 @@ logging:
# ignored: /**,/swagger*,/webjars/**,/v2/**,/swagger-resources/**
swagger_enable: true
eureka:
client:
service-url:
defaultZone: http://localhost:10001/eureka
#eureka:
# client:
# service-url:
# defaultZone: http://localhost:10001/eureka
apollo:
bootstrap:
enabled: true
meta: http://localhost:8080
#apollo appId
app:
id: order_service
package com.freemud.springbootdemo;
import com.freemud.demo.cache.DictRedisHashCache;
import com.freemud.demo.dto.DictTypeDto;
import com.freemud.demo.dto.PageData;
import com.freemud.demo.dto.PageReq;
import com.freemud.demo.model.TDictType;
import com.freemud.demo.service.IDictTypeService;
import com.freemud.demo.service.impl.DictTypeServiceImpl;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* Created by chenwenshun on 2018/11/2.
*/
public class ServiceMockTest {
DictTypeServiceImpl dictTypeService;
@Mock
DictRedisHashCache dictRedisHashCache;
@Before
public void initMocks(){
dictTypeService = new DictTypeServiceImpl();
MockitoAnnotations.initMocks(this);
dictTypeService.setDictRedisHashCache(dictRedisHashCache);
// TDictType dictType = new TDictType();
// dictType.setDictTypeCd("apiUrl");
// Mockito.when(dictTypeService.loadDictByCd("aaa")).thenReturn(dictType);
}
@Test
public void testFindPageDict(){
PageReq pageReq = new PageReq();
pageReq.setDictTypeName("di");
dictTypeService.loadDatasByTypeCd("",true);
System.out.println("=====");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment