diff --git a/pom.xml b/pom.xml
index d1c7ffd..7a91dde 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,7 +17,7 @@
test-eureka-client-test
test-kafka
test-eureka-web
- test-auth-token
+ test-netty
diff --git a/test-auth-token/pom.xml b/test-auth-token/pom.xml
deleted file mode 100644
index 263c623..0000000
--- a/test-auth-token/pom.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
- wsd
- com.springboot.test
- 1.0-SNAPSHOT
-
- 4.0.0
-
- test-auth-token
- token
- 获取验证的token,包含有权限信息(角色 及 权限资源)
-
-
-
-
- org.springframework.cloud
- spring-cloud-starter-archaius
- 1.3.4.RELEASE
-
-
-
- org.springframework.cloud
- spring-cloud-starter-eureka
- 1.3.4.RELEASE
-
-
-
- org.springframework.cloud
- spring-cloud-starter-feign
- 1.3.0.RELEASE
-
-
-
-
- org.apache.commons
- commons-lang3
- 3.7
-
-
-
-
- io.jsonwebtoken
- jjwt
- 0.7.0
-
-
-
-
- com.springboot.test
- test-eureka-client-test
- 1.0-SNAPSHOT
-
-
-
-
-
\ No newline at end of file
diff --git a/test-auth-token/src/main/java/com/test/auth/token/AuthApplication.java b/test-auth-token/src/main/java/com/test/auth/token/AuthApplication.java
deleted file mode 100644
index b8ddcf9..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/AuthApplication.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.test.auth.token;
-
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-
-/**
- * ======================
- * Created By User: RXK
- * Date: 2018/1/29 17:31
- * Version: V1.0
- * Description:
- * ======================
- */
-//TODO 增加客户端的启动注解以及熔断注解
-@MapperScan(basePackages = {"com.test.auth.token.dao"})
-@SpringBootApplication
-public class AuthApplication
-{
- public static void main(String[] args){
- new SpringApplicationBuilder(AuthApplication.class).web(true).run(args);
- }
-
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/dao/UserMapper.java b/test-auth-token/src/main/java/com/test/auth/token/dao/UserMapper.java
deleted file mode 100644
index 41674a8..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/dao/UserMapper.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.test.auth.token.dao;
-
-import org.springframework.stereotype.Repository;
-
-/**
- * ======***********=========
- * Created By User: RXK
- * Date: 2018/1/29 17:48
- * Version: V1.0
- * Description:用户信息
- * ======***********=========
- */
-@Repository
-public interface UserMapper
-{
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/service/AuthTokenService.java b/test-auth-token/src/main/java/com/test/auth/token/service/AuthTokenService.java
deleted file mode 100644
index fe9122d..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/service/AuthTokenService.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.test.auth.token.service;
-
-/**
- * ======***********=========
- * Created By User: RXK
- * Date: 2018/1/29 17:35
- * Version: V1.0
- * Description:根据用户的账号 获取当前用户的角色以及权限 产生对应的Token
- * ======***********=========
- */
-public interface AuthTokenService
-{
- /**
- * 根据账号或者手机号码 获取token
- * @param account :账号或者 手机号码
- */
- void getToekn(String account);
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/service/impl/AuthTokenServiceImpl.java b/test-auth-token/src/main/java/com/test/auth/token/service/impl/AuthTokenServiceImpl.java
deleted file mode 100644
index 814e927..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/service/impl/AuthTokenServiceImpl.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.test.auth.token.service.impl;
-
-import com.test.auth.token.service.AuthTokenService;
-import com.test.auth.token.service.rpc.UserService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-/**
- * ======================
- * Created By User: RXK
- * Date: 2018/1/29 17:38
- * Version: V1.0
- * Description: 产生用户token
- * ======================
- */
-@Service
-public class AuthTokenServiceImpl implements AuthTokenService
-{
- @Autowired
- private UserService userService ;
-
- @Override
- public void getToekn(String account)
- {
-
- }
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/service/impl/TokenUtilsServiceImpl.java b/test-auth-token/src/main/java/com/test/auth/token/service/impl/TokenUtilsServiceImpl.java
deleted file mode 100644
index 6f5b254..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/service/impl/TokenUtilsServiceImpl.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.test.auth.token.service.impl;
-
-import com.test.auth.token.service.rpc.TokenUtilsService;
-import com.test.auth.token.util.RSAEncryptUtil;
-import org.apache.commons.lang3.ArrayUtils;
-import org.springframework.stereotype.Service;
-
-import java.security.interfaces.RSAPrivateKey;
-import java.util.Base64;
-
-/**
- * ======================
- * Created By User: RXK
- * Date: 2018/3/2 9:20
- * Version: V1.0
- * Description:
- * ======================
- */
-@Service
-public class TokenUtilsServiceImpl implements TokenUtilsService {
-
- private static final String PRIVATE_KEY_FILE = "D:/RAS/private.txt";
-
-
- @Override
- public String decodePassword(String password) {
-
- if(null == password){
- return null ;
- }
- byte[] privateKey = RSAEncryptUtil.decoderByPrivateKey(password.getBytes(), RSAEncryptUtil.getPrivateKeyByString(RSAEncryptUtil.getKeyByFile(PRIVATE_KEY_FILE)));
-
- if(ArrayUtils.isEmpty(privateKey)){
- return null;
- }
-
- byte[] decode = Base64.getDecoder().decode(privateKey);
-
- return new String(decode);
- }
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/service/rpc/TokenUtilsService.java b/test-auth-token/src/main/java/com/test/auth/token/service/rpc/TokenUtilsService.java
deleted file mode 100644
index 7af8b83..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/service/rpc/TokenUtilsService.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.test.auth.token.service.rpc;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-/**
- * ======***********=========
- * Created By User: RXK
- * Date: 2018/3/2 9:07
- * Version: V1.0
- * Description: 用于token 远程调用的工具service
- * ======***********=========
- */
-public interface TokenUtilsService {
-
- static final String BASE_URL = "rpc/rsa";
-
- /**
- * 用户进行登录时 对密码进行解密操作
- * @param password:用户密码
- * @return :解密以后的密码
- */
- @RequestMapping(value = BASE_URL+"/util",method = RequestMethod.POST)
- String decodePassword(String password);
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/service/rpc/UserService.java b/test-auth-token/src/main/java/com/test/auth/token/service/rpc/UserService.java
deleted file mode 100644
index 5dd2b87..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/service/rpc/UserService.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.test.auth.token.service.rpc;
-
-import com.test.eureka.client.test.service.MemberClientService;
-import org.springframework.cloud.netflix.feign.FeignClient;
-
-/**
- * ======***********=========
- * Created By User: RXK
- * Date: 2018/1/29 17:54
- * Version: V1.0
- * Description:
- * ======***********=========
- */
-@FeignClient(name = "test-eureka-client")
-public interface UserService extends MemberClientService
-{
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/util/JWTutil.java b/test-auth-token/src/main/java/com/test/auth/token/util/JWTutil.java
deleted file mode 100644
index b2832f8..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/util/JWTutil.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.test.auth.token.util;
-
-/**
- * ======================
- * Created By User: RXK
- * Date: 2018/1/29 17:10
- * Version: V1.0
- * Description:产生token
- * ======================
- */
-public class JWTutil
-{
-
-
-
-
-
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/util/RSAEncryptUtil.java b/test-auth-token/src/main/java/com/test/auth/token/util/RSAEncryptUtil.java
deleted file mode 100644
index 460d5bc..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/util/RSAEncryptUtil.java
+++ /dev/null
@@ -1,420 +0,0 @@
-package com.test.auth.token.util;
-
-import org.apache.commons.lang3.ArrayUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.util.StringUtils;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import java.io.*;
-import java.security.*;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Base64;
-import java.util.Objects;
-
-/**
- * ======================
- * Created By User: RXK
- * Date: 2018/1/27 14:34
- * Version: V1.0
- * Description: 通过RSA 获取 Public_key 及 Private_key
- * ======================
- */
-public class RSAEncryptUtil
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(RSAEncryptUtil.class);
-
- //使用的加密算法
- private static final String KEY_ALGORITHM = "RSA";
-
- //长度 (单位 位;)RSA得到的密文长度不能超过 密匙长度的11位;
- private static final Integer KEY_SIZE = 1024;
-
- //将公匙 和 私匙 保存到指定的 文件中
- private static final String PRIVATE_KEY_FILE = "D:/RAS/private.txt";
- private static final String PUBLIC_KEY_FILE = "D:/RAS/public.txt";
-
-
- public static void main(String[] args)
- {
- String text = "123456789";
- //获取密匙对
-// getKeyPair();
- //通过公匙对内容加密
- byte[] bytes = encodeByPublicKey(text.getBytes(), getPublicKeyByStr(getKeyByFile(PUBLIC_KEY_FILE)));
- String string = Base64.getEncoder().encodeToString(bytes);
- System.out.println(string);
- }
-
-
- /**
- * 获取 密匙对
- */
- private static void getKeyPair()
- {
- try
- {
- KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_ALGORITHM);
- kpg.initialize(KEY_SIZE, new SecureRandom());
-
- KeyPair keyPair = kpg.generateKeyPair();
-
- RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
- RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
-
- String strPublicKey = Base64.getEncoder().encodeToString(publicKey.getEncoded());
- String strPrivateKey = Base64.getEncoder().encodeToString(privateKey.getEncoded());
-
- LOGGER.info("kpg.generateKeyPair() 生成的公匙:" + strPublicKey);
- LOGGER.info("kpg.generateKeyPair() 生成的私匙:" + strPrivateKey);
-
- FileWriter privateKeyFW = new FileWriter(PRIVATE_KEY_FILE);
- FileWriter publicKeyFW = new FileWriter(PUBLIC_KEY_FILE);
-
- BufferedWriter privateKeyBw = new BufferedWriter(privateKeyFW);
- BufferedWriter publicKeyBw = new BufferedWriter(publicKeyFW);
-
- publicKeyBw.write(strPublicKey);
- privateKeyBw.write(strPrivateKey);
-
- privateKeyBw.flush();
- publicKeyBw.flush();
-
- privateKeyBw.close();
- publicKeyBw.close();
-
- privateKeyFW.close();
- publicKeyFW.close();
-
- LOGGER.info("写入完成");
- } catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- LOGGER.info("加密算法有误,无法找到对应的加密算法");
- } catch (IOException e)
- {
- e.printStackTrace();
- LOGGER.info("创建文件出现异常");
- }
- }
-
-
- /**
- * 从文件中 读取 密匙
- *
- * @param filePath :文件路径
- */
- public static String getKeyByFile(String filePath)
- {
- try
- {
- if (StringUtils.isEmpty(filePath))
- {
- LOGGER.info("文件路径为空");
- return null;
- }
- BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
- StringBuilder sb = new StringBuilder();
- String readLine = "";
- if ((readLine = bufferedReader.readLine()) != null)
- {
- sb.append(readLine);
- }
-
- bufferedReader.close();
-
- return sb.toString();
-
- } catch (FileNotFoundException e)
- {
- e.printStackTrace();
- LOGGER.info("未找到对应的文件");
- } catch (IOException e)
- {
- e.printStackTrace();
- LOGGER.info("读取文件出现异常");
- }
- return null;
- }
-
-
- /**
- * 从 字符串中 还原 公匙
- *
- * @param string : 字符串
- * @return : RSApublicKey 公匙
- */
- public static RSAPublicKey getPublicKeyByStr(String string)
- {
- if (StringUtils.isEmpty(string))
- {
- LOGGER.info("缺少字符串来源");
- return null;
- }
- try
- {
- byte[] decode = Base64.getDecoder().decode(string);
- //使用 公匙规范 还原 公匙
- X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decode);
- KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
- return (RSAPublicKey) factory.generatePublic(x509EncodedKeySpec);
-
- } catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- LOGGER.info("指定的算法有误");
- } catch (InvalidKeySpecException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的公匙规范");
- }
- return null;
- }
-
-
- /**
- * 从给定的字符串中加载 私匙
- *
- * @param string :指定的字符串
- * @return : RSAPrivatekey
- */
- public static RSAPrivateKey getPrivateKeyByString(String string)
- {
- if (StringUtils.isEmpty(string))
- {
- LOGGER.info("原字符串为空");
- return null;
- }
- try
- {
- byte[] decode = Base64.getDecoder().decode(string);
- //私匙还原规范
- PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(decode);
-
- KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
-
- return (RSAPrivateKey) factory.generatePrivate(pkcs8);
-
- } catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- LOGGER.info("找不到指定的算法");
- } catch (InvalidKeySpecException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的规范");
- }
- return null;
- }
-
- /**
- * 公匙 加密
- *
- * @param content :加密内容
- * @param publicKey : 公匙
- */
- public static byte[] publicKeyEncrypt(byte[] content, RSAPublicKey publicKey)
- {
- if (Objects.isNull(publicKey) || ArrayUtils.isEmpty(content))
- {
- LOGGER.info("通过publicKey加密时 参数有误");
- return null;
- }
- try
- {
- Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
- return cipher.doFinal(content);
- } catch (NoSuchAlgorithmException | NoSuchPaddingException e)
- {
- e.printStackTrace();
- LOGGER.info("找不到指定的算法出现异常或者。。。。。。");
-
- } catch (InvalidKeyException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的key异常");
-
- } catch (BadPaddingException | IllegalBlockSizeException e)
- {
- e.printStackTrace();
- LOGGER.info("使用公匙加密");
- }
- return null;
- }
-
-
- /**
- * 通过 私匙进行 加密
- *
- * @param content : 需要加密的过程
- * @param privateKey :私匙
- */
- public static byte[] encodeByPrivateKey(byte[] content, RSAPrivateKey privateKey)
- {
- if (ArrayUtils.isEmpty(content) || Objects.isNull(privateKey))
- {
- LOGGER.info("通过privateKey 加密时,参数有误");
- return null;
- }
-
- try
- {
- Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
-
- cipher.init(Cipher.ENCRYPT_MODE, privateKey);
-
- return cipher.doFinal(content);
- } catch (NoSuchAlgorithmException | NoSuchPaddingException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的算法异常");
- } catch (InvalidKeyException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的privateKey异常");
- } catch (BadPaddingException | IllegalBlockSizeException e)
- {
- e.printStackTrace();
- LOGGER.info("privateKey加密时出现异常");
- }
-
- return null;
- }
-
-
- /**
- * 通过私匙进行 解密
- * @param content : 解密的内容
- * @param privateKey :私匙
- */
- public static byte[] decoderByPrivateKey(byte[] content, RSAPrivateKey privateKey)
- {
- if (ArrayUtils.isEmpty(content) || Objects.isNull(privateKey))
- {
- LOGGER.info("私匙机密时参数有误");
- return null ;
- }
-
- try
- {
- Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
-
- cipher.init(Cipher.DECRYPT_MODE, privateKey);
- return cipher.doFinal(content);
- } catch (NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e)
- {
- e.printStackTrace();
- LOGGER.info("私匙解密的过程中出现异常");
- } catch (InvalidKeyException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的私匙");
- }
- return null;
- }
-
-
- /**
- * 公匙解密过程
- *
- * @param content : 解密内容
- * @param publicKey : 公匙
- */
- public static byte[] decoderByPublicKey(byte[] content, RSAPublicKey publicKey)
- {
- if (ArrayUtils.isEmpty(content) || Objects.isNull(publicKey))
- {
- LOGGER.info("publicKey解密过程中 参数有误");
- return null;
- }
- try
- {
- Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
-
- cipher.init(Cipher.DECRYPT_MODE, publicKey);
-
- return cipher.doFinal(content);
-
- } catch (NoSuchAlgorithmException | NoSuchPaddingException e)
- {
- e.printStackTrace();
- LOGGER.info("解密时,没有找到指定的算法");
- } catch (InvalidKeyException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的公匙");
- } catch (BadPaddingException | IllegalBlockSizeException e)
- {
- e.printStackTrace();
- LOGGER.info("通过公匙解密时出现异常");
- }
- return null;
- }
-
- /**
- * 公匙 加密
- *
- * @param content : 加密的内容
- * @param publicKey : 公匙
- */
- public static byte[] encodeByPublicKey(byte[] content, RSAPublicKey publicKey)
- {
- if (ArrayUtils.isEmpty(content) || Objects.isNull(publicKey))
- {
- LOGGER.info("公匙加密的过程中 参数有误");
- return null;
- }
-
- try
- {
- Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
-
- cipher.init(Cipher.ENCRYPT_MODE, publicKey);
-
- return cipher.doFinal(content);
- } catch (NoSuchAlgorithmException | NoSuchPaddingException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的算法");
- } catch (InvalidKeyException e)
- {
- e.printStackTrace();
- LOGGER.debug("无效的私匙");
- } catch (BadPaddingException | IllegalBlockSizeException e)
- {
- e.printStackTrace();
- LOGGER.debug("PrivateKey加密时 出现异常");
- }
- return null;
- }
-
- /**
- * 将字节内容 通过 Base64 加密成 字符串
- *
- * @param content : 内容
- * @return : 加密以后的字符串内容
- */
- public static String encodeByBase64(byte[] content)
- {
- return Base64.getEncoder().encodeToString(content);
- }
-
- /**
- * 通过Base64 将 字符串 转换成 字节数组
- *
- * @param content : 字符串内容
- * @return : 字节数组
- */
- public static byte[] decodeByBase64(String content)
- {
- return Base64.getDecoder().decode(content);
- }
-}
diff --git a/test-auth-token/src/main/java/com/test/auth/token/util/RSASign.java b/test-auth-token/src/main/java/com/test/auth/token/util/RSASign.java
deleted file mode 100644
index 46d41d6..0000000
--- a/test-auth-token/src/main/java/com/test/auth/token/util/RSASign.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package com.test.auth.token.util;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.security.*;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.InvalidKeySpecException;
-import java.security.spec.PKCS8EncodedKeySpec;
-import java.security.spec.X509EncodedKeySpec;
-import java.util.Base64;
-
-/**
- * ======================
- * Created By User: RXK
- * Date: 2018/1/28 11:45
- * Version: V1.0
- * Description: 签名 以及 验签类
- * ======================
- */
-public class RSASign
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(RSASign.class);
-
-
- private static final String PRIVATE_KEY_FILE_PATH = "D:/RAS/private.txt";
-
- //签名的算法 可在sign中查找
- private static final String SIGN_ALGORITHM = "SHA1withRSA";
-
- private static final String KEY_ALGORITHM = "RSA";
-
- /**
- * 通过私匙 签发 签名
- *
- * @param data :加密数据
- * @param privateKey : 私匙
- */
- public static String sign(byte[] data, String privateKey)
- {
- try
- {
- //先使用Base64解密
- byte[] privateKeyBytes = Base64.getDecoder().decode(privateKey);
- //使用规范获取私匙
- PKCS8EncodedKeySpec pkcs8 = new PKCS8EncodedKeySpec(privateKeyBytes);
-
- //使用工厂 进行初始化
- KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);
- //更具规范 从工厂中获取到私匙
- RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) factory.generatePrivate(pkcs8);
-
- //获取签名对象
- Signature signature = Signature.getInstance(SIGN_ALGORITHM);
- //有私匙 初始化签名
- signature.initSign(rsaPrivateKey);
- signature.update(data);
-
- return Base64.getEncoder().encodeToString(signature.sign());
-
- } catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- LOGGER.info("签名时,找不到指定的算法");
- } catch (InvalidKeyException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的私匙");
- } catch (SignatureException e)
- {
- e.printStackTrace();
- LOGGER.info("签名时出现异常");
- } catch (InvalidKeySpecException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的规范");
- }
- return null;
- }
-
-
- /**
- * 验签
- *
- * @param content : 原始签名内容
- * @param publicKey :公匙
- * @param sign :使用Base64加密后的签名串
- */
- public static boolean checkSign(String content, String publicKey, String sign)
- {
- try
- {
- //处理字符串公匙
- byte[] publicKeyBytes = Base64.getDecoder().decode(publicKey);
-
- X509EncodedKeySpec x509 = new X509EncodedKeySpec(publicKeyBytes);
- KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
- RSAPublicKey rsaPublicKey = (RSAPublicKey) keyFactory.generatePublic(x509);
- Signature signature = Signature.getInstance(SIGN_ALGORITHM);
- signature.initVerify(rsaPublicKey);
- signature.update(content.getBytes());
-
- return signature.verify(RSAEncryptUtil.decodeByBase64(sign));
-
- } catch (NoSuchAlgorithmException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的算法签名");
- } catch (InvalidKeySpecException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的公匙规范");
- } catch (InvalidKeyException e)
- {
- e.printStackTrace();
- LOGGER.info("无效的公匙");
- } catch (SignatureException e)
- {
- e.printStackTrace();
- LOGGER.info("更新数据时,出现异常");
- }
- return false;
- }
-
-
-}
diff --git a/test-auth-token/src/main/resources/application.yml b/test-auth-token/src/main/resources/application.yml
deleted file mode 100644
index 1808f1c..0000000
--- a/test-auth-token/src/main/resources/application.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-server:
- port: 9555
-spring:
- application:
- name: test-auth-token
-eureka:
- instance:
- lease-renewal-interval-in-seconds: 10
- lease-expiration-duration-in-seconds: 30
- client:
- register-with-eureka: true
- fetch-registry: true
- registry-fetch-interval-seconds: 30
- service-url:
- defaultZone: http://testService:123aaa@127.0.0.1:9888/eureka/,http://testService:123aaa@127.0.0.1:9999/eureka/
-endpoints:
- enabled: true
-feign:
- hystrix:
- enable: true
- compression:
- request:
- enable: true
- mime-types: application/json,text/html,application/xml
- min-request-size: 2048
- response:
- enable: true
\ No newline at end of file
diff --git a/test-auth-token/src/test/java/TestRSA.java b/test-auth-token/src/test/java/TestRSA.java
deleted file mode 100644
index 4310270..0000000
--- a/test-auth-token/src/test/java/TestRSA.java
+++ /dev/null
@@ -1,93 +0,0 @@
-import com.test.auth.token.util.RSAEncryptUtil;
-import com.test.auth.token.util.RSASign;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.security.interfaces.RSAPrivateKey;
-import java.security.interfaces.RSAPublicKey;
-
-/**
- * ======================
- * Created By User: RXK
- * Date: 2018/1/29 10:01
- * Version: V1.0
- * Description: 公私匙 分别加密 然后再检验以及验签
- * ======================
- */
-public class TestRSA
-{
- private static final Logger LOGGER = LoggerFactory.getLogger(TestRSA.class);
-
-
- private static final String PRIVATE_KEY_FILE = "D:/RAS/private.txt";
- private static final String PUBLIC_KEY_FILE = "D:/RAS/public.txt";
-
- public static void main(String[] args)
- {
- //需要加密的 内容
- String encryptText = "测试私匙加密公匙解密的文字";
-
- LOGGER.info("私匙加密 ------- 公匙解密");
-
- //从文件中加载私匙
- String privateKeyByFile = RSAEncryptUtil.getKeyByFile(PRIVATE_KEY_FILE);
-
- //将字符串还原成私匙
- RSAPrivateKey rsaPrivateKey = RSAEncryptUtil.getPrivateKeyByString(privateKeyByFile);
-
- //加密以后的内容
- byte[] encodeData = RSAEncryptUtil.encodeByPrivateKey(encryptText.getBytes(), rsaPrivateKey);
-
- //Base64加密
- String secretData = RSAEncryptUtil.encodeByBase64(encodeData);
-
- //从文件中加载公匙
- String publicKeyByFile = RSAEncryptUtil.getKeyByFile(PUBLIC_KEY_FILE);
-
- //将文件中的公匙通过 Base64 以及 公匙规范 工厂 得到公匙
- RSAPublicKey rsaPublicKey = RSAEncryptUtil.getPublicKeyByStr(publicKeyByFile);
-
- // 通过公匙解密
- byte[] decodeDataByte = RSAEncryptUtil.decoderByPublicKey(RSAEncryptUtil.decodeByBase64(secretData), rsaPublicKey);
-
- assert decodeDataByte != null;
- String decodeData = new String(decodeDataByte);
-
- System.out.println("原文是:"+encryptText);
- System.out.println("加密以后是:"+secretData);
- System.out.println("解密以后是:"+decodeData);
-
- System.out.println("----------------------------------------------------------------------------------------");
-
- //对需要加密的内容使用私匙进行 签名; 一起发送给 另一方
- String sign = RSASign.sign(encryptText.getBytes(), RSAEncryptUtil.getKeyByFile(PRIVATE_KEY_FILE));
-
- System.out.println("签名串:"+sign);
-
- System.out.println("************************验签**********************************");
-
- //接收方 使用公匙 先解密数据,然后再使用公匙 以及 签名 对解密的数据进行 验签 确保没有被更改过
- boolean checkSign = RSASign.checkSign(decodeData, RSAEncryptUtil.getKeyByFile(PUBLIC_KEY_FILE), sign);
- System.out.println("检验结果:"+checkSign);
-
-
- LOGGER.info("公匙加密 ------------------------------ 私匙解密 ");
-
- String testText = "测试使用公匙加密后然后使用私匙解密的过程";
-
- //获取到公匙 并对内容进行加密
- byte[] encodeByPublicKey = RSAEncryptUtil.encodeByPublicKey(testText.getBytes(), RSAEncryptUtil.getPublicKeyByStr(RSAEncryptUtil.getKeyByFile(PUBLIC_KEY_FILE)));
- String strEncodeByPublicKey = RSAEncryptUtil.encodeByBase64(encodeByPublicKey);
-
- //获取到私匙 并对内容进行 解密
- byte[] decoderByPrivateKey = RSAEncryptUtil.decoderByPrivateKey(RSAEncryptUtil.decodeByBase64(strEncodeByPublicKey), RSAEncryptUtil.getPrivateKeyByString(RSAEncryptUtil.getKeyByFile(PRIVATE_KEY_FILE)));
-
- assert decoderByPrivateKey != null;
- String text = new String(decoderByPrivateKey);
-
- System.out.println("公匙加密以后的内容:"+strEncodeByPublicKey);
- System.out.println("私匙解密以后的内容:"+text);
- }
-
-
-}
diff --git a/test-eureka-client-test/src/main/java/com/test/eureka/client/test/service/ResourceClientService.java b/test-eureka-client-test/src/main/java/com/test/eureka/client/test/service/ResourceClientService.java
index d45897f..fe92d47 100644
--- a/test-eureka-client-test/src/main/java/com/test/eureka/client/test/service/ResourceClientService.java
+++ b/test-eureka-client-test/src/main/java/com/test/eureka/client/test/service/ResourceClientService.java
@@ -13,7 +13,6 @@
* Description: 资源
* ======================
*/
-@RestController
public interface ResourceClientService
{
diff --git a/test-eureka-client/pom.xml b/test-eureka-client/pom.xml
index 661e9a8..3f2ada6 100644
--- a/test-eureka-client/pom.xml
+++ b/test-eureka-client/pom.xml
@@ -38,7 +38,12 @@
org.springframework.boot
- spring-boot-actuator
+ spring-boot-starter-actuator
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
@@ -57,8 +62,13 @@
org.springframework.boot
spring-boot-starter-jdbc
-
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
local
@@ -66,9 +76,6 @@
local
-
- true
-
dev
@@ -76,9 +83,11 @@
dev
dev
+
+ true
+
-
@@ -90,9 +99,9 @@
src/main/resources
true
+
- **/*.xml
- **/application-${profileActive}.yml
+ **/*.*
@@ -131,6 +140,4 @@
-
-
\ No newline at end of file
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/EurekaClientApplication.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/EurekaClientApplication.java
index a022e49..0e081ca 100644
--- a/test-eureka-client/src/main/java/com/test/eureka/web/client/EurekaClientApplication.java
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/EurekaClientApplication.java
@@ -25,20 +25,18 @@
* Description:
* ======================
*/
-@MapperScan(annotationClass = Repository.class,basePackages = {"com.test.eureka.web.client.dao"})
-@ComponentScan(basePackages = {"com.test.eureka.web.client"})
@SpringBootApplication
+@MapperScan(annotationClass = Repository.class, basePackages = {"com.test.eureka.web.client.dao"})
+@ComponentScan(basePackages = {"com.test.eureka.web.client"})
@EnableTransactionManagement
-@EnableFeignClients
-@EnableDiscoveryClient
+//@EnableFeignClients
+//@EnableDiscoveryClient
@ServletComponentScan
-@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
+@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class})
@Import(DruidConfig.class)
-public class EurekaClientApplication
-{
- public static void main(String[]args){
- new SpringApplicationBuilder(EurekaClientApplication.class).web(true)
- .run(args);
- }
+public class EurekaClientApplication {
+ public static void main(String[] args) {
+ new SpringApplicationBuilder(EurekaClientApplication.class).web(true).run(args);
+ }
}
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/ChangeDataSourceAop.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/ChangeDataSourceAop.java
new file mode 100644
index 0000000..e46e6f6
--- /dev/null
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/ChangeDataSourceAop.java
@@ -0,0 +1,85 @@
+package com.test.eureka.web.client.config;
+
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.Stack;
+
+/**
+ * ======================
+ * Created By User: RXK
+ * Date: 2018/6/9 17:27
+ * Version: V1.0
+ * Description: 切换数据源的 AOP 在 进入Service 层之前 切换数据源
+ * 按照包结构 或者 注解 拦截
+ * 拦截以后 将本地线程变量 中的内容删除
+ *
+ * 注解 解释:
+ * 切面 @Aspect
+ * ======================
+ */
+@Aspect
+@Order(-1) //确保 该切面执行的顺序比 事务要早
+@Component
+public class ChangeDataSourceAop {
+
+
+ private Stack booleanStack = new Stack<>();
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ChangeDataSourceAop.class);
+
+ @Pointcut("execution(* com.test.eureka.web.client.rpc.service.*.*(..)) && @annotation(com.test.eureka.web.client.config.ReadDataSource)")
+ public void pointCut() {
+ }
+
+
+ @Before("pointCut()")
+ public void beforeSetRedDataSourceType() {
+ LOGGER.info("进入设置读数据库的AOP");
+ Boolean flag = false;
+
+ if (StringUtils.isEmpty(DataSourceLookUpKeyThreadLocal.getDataSourceLookUpKey())) {
+ LOGGER.info("设置当前的线程为 read");
+ DataSourceLookUpKeyThreadLocal.setReadDataSourceLookUpKey();
+
+ flag = true;
+ }
+
+ booleanStack.push(flag);
+ }
+
+
+ @Before("pointCut()")
+ public void beforeSetWriteDataSourceType() {
+ LOGGER.info("设置当前线程中的数据库类型为读");
+ Boolean flag = false;
+
+ if (StringUtils.isEmpty(DataSourceLookUpKeyThreadLocal.getDataSourceLookUpKey())) {
+ LOGGER.info("设置当前的线程为 write");
+ DataSourceLookUpKeyThreadLocal.setWriteDataSourceLookUpKey();
+
+ flag = true;
+ }
+
+ booleanStack.push(flag);
+ }
+
+
+ @After("pointCut()")
+ public void after(){
+ if(booleanStack.pop()){
+ LOGGER.info("去除当前线程中的 数据库读写的类型");
+ DataSourceLookUpKeyThreadLocal.remove();
+ }
+ }
+
+
+
+}
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/CoustomTranstionManagement.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/CoustomTranstionManagement.java
new file mode 100644
index 0000000..d681ffc
--- /dev/null
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/CoustomTranstionManagement.java
@@ -0,0 +1,36 @@
+package com.test.eureka.web.client.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+
+/**
+ * ======================
+ * Created By User: RXK
+ * Date: 2018/6/10 10:47
+ * Version: V1.0
+ * Description: 自定义 事务管理
+ * ======================
+ */
+@Configuration
+@EnableTransactionManagement
+public class CoustomTranstionManagement extends DataSourceTransactionManagerAutoConfiguration {
+
+
+ @Resource(name = "dataSource")
+ private DataSource writerDataSource;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CoustomTranstionManagement.class);
+
+ public DataSourceTransactionManager transactionManager(){
+ LOGGER.info("使用读数据库时 进事务管理器");
+ return new DataSourceTransactionManager(writerDataSource);
+ }
+
+}
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DataSourceLookUpKeyThreadLocal.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DataSourceLookUpKeyThreadLocal.java
new file mode 100644
index 0000000..ed5f648
--- /dev/null
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DataSourceLookUpKeyThreadLocal.java
@@ -0,0 +1,39 @@
+package com.test.eureka.web.client.config;
+
+import com.test.eureka.web.client.enums.DatasourceEnum;
+
+/**
+ * ======================
+ * Created By User: RXK
+ * Date: 2018/6/7 22:45
+ * Version: V1.0
+ * Description: 使用当前线程 保存 使用的数据源的key
+ * 一是可以解决并发操作 保证线程安全
+ * 二是 读库有多个数据源时 不会随意的跟换
+ * ======================
+ */
+public class DataSourceLookUpKeyThreadLocal {
+
+ private static final ThreadLocal local = new ThreadLocal<>();
+
+ public static void setReadDataSourceLookUpKey(){
+ local.set(DatasourceEnum.READ.name());
+ }
+
+ public static void setWriteDataSourceLookUpKey(){
+ local.set(DatasourceEnum.WRITE.name());
+ }
+
+
+ public static String getDataSourceLookUpKey(){
+ return local.get();
+ }
+
+ /**
+ * 使用完后 必须删除 否则 很可能会操作内存溢出
+ */
+ public static void remove(){
+ local.remove();
+ }
+
+}
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/CoustomerDataSource.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DataSourceProperties.java
similarity index 94%
rename from test-eureka-client/src/main/java/com/test/eureka/web/client/config/CoustomerDataSource.java
rename to test-eureka-client/src/main/java/com/test/eureka/web/client/config/DataSourceProperties.java
index 94d101e..f0b4086 100644
--- a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/CoustomerDataSource.java
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DataSourceProperties.java
@@ -10,10 +10,9 @@
* Description:
* ======================
*/
-@ConfigurationProperties(prefix = CoustomerDataSource.DATA_SOURCE )
-public class CoustomerDataSource {
-
- public static final String DATA_SOURCE = "spring.datasource";
+@ConfigurationProperties(prefix = DataSourceProperties.DATA_SOURCE )
+public class DataSourceProperties {
+ public static final String DATA_SOURCE = "spring.datasource.master";
private String username ;
@@ -39,7 +38,7 @@ public class CoustomerDataSource {
private String validationQuery ;
- private boolean testWhileIdle ;
+ private Boolean testWhileIdle ;
private Boolean testOnBorrow ;
@@ -53,9 +52,6 @@ public class CoustomerDataSource {
private String type;
- public CoustomerDataSource() {
- }
-
public String getUsername() {
return username;
}
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DruidConfig.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DruidConfig.java
index 3bc4469..9cda488 100644
--- a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DruidConfig.java
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/DruidConfig.java
@@ -6,11 +6,10 @@
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
-import org.mybatis.spring.SqlSessionFactoryBean;
+import org.apache.commons.lang.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
@@ -18,6 +17,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
+import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -31,13 +31,20 @@
* ======================
*/
@Configuration
-@EnableConfigurationProperties({CoustomerDataSource.class})
+@EnableConfigurationProperties({DataSourceProperties.class,SlaveDataSourceProperties.class})
public class DruidConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(DruidConfig.class);
+ private final DataSourceProperties writeProperties;
+
+ private final SlaveDataSourceProperties readProperties;
+
@Autowired
- private CoustomerDataSource properties;
+ public DruidConfig(DataSourceProperties dataSourceProperties,SlaveDataSourceProperties readProperties) {
+ this.writeProperties = dataSourceProperties;
+ this.readProperties = readProperties;
+ }
@Bean
public ServletRegistrationBean druidStatViewServlet() {
@@ -61,32 +68,35 @@ public FilterRegistrationBean registrationBean() {
return bean;
}
- @Bean
+ /**
+ * 作为主库 也是 唯一一个 写库
+ */
+ @Bean(name = "dataSource")
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
- dataSource.setUrl(properties.getUrl());
- dataSource.setUsername(properties.getUsername());
- dataSource.setPassword(properties.getPassword());
- dataSource.setDriverClassName(properties.getDriverClassName());
-
- dataSource.setTestWhileIdle(properties.getTestWhileIdle());
- dataSource.setTestOnReturn(properties.getTestOnReturn());
- dataSource.setTestOnBorrow(properties.getTestOnBorrow());
- dataSource.setMaxActive(properties.getMaxActive());
- dataSource.setMaxWait(properties.getMaxWait());
- dataSource.setMinIdle(properties.getMinIdle());
- dataSource.setInitialSize(properties.getInitialSize());
- dataSource.setValidationQuery(properties.getValidationQuery());
-
- dataSource.setMaxOpenPreparedStatements(properties.getMaxOpenPreparedStatements());
- dataSource.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRunsMillis());
- dataSource.setPoolPreparedStatements(properties.getPoolPreparedStatements());
- dataSource.setTimeBetweenConnectErrorMillis(properties.getTimeBetweenEvictionRunsMillis());
- dataSource.setConnectionProperties(properties.getConnectionProperties());
+ dataSource.setUrl(writeProperties.getUrl());
+ dataSource.setUsername(writeProperties.getUsername());
+ dataSource.setPassword(writeProperties.getPassword());
+ dataSource.setDriverClassName(writeProperties.getDriverClassName());
+
+ dataSource.setTestWhileIdle(writeProperties.getTestWhileIdle());
+ dataSource.setTestOnReturn(writeProperties.getTestOnReturn());
+ dataSource.setTestOnBorrow(writeProperties.getTestOnBorrow());
+ dataSource.setMaxActive(writeProperties.getMaxActive());
+ dataSource.setMaxWait(writeProperties.getMaxWait());
+ dataSource.setMinIdle(writeProperties.getMinIdle());
+ dataSource.setInitialSize(writeProperties.getInitialSize());
+ dataSource.setValidationQuery(writeProperties.getValidationQuery());
+
+ dataSource.setMaxOpenPreparedStatements(writeProperties.getMaxOpenPreparedStatements());
+ dataSource.setTimeBetweenEvictionRunsMillis(writeProperties.getTimeBetweenEvictionRunsMillis());
+ dataSource.setPoolPreparedStatements(writeProperties.getPoolPreparedStatements());
+ dataSource.setTimeBetweenConnectErrorMillis(writeProperties.getTimeBetweenEvictionRunsMillis());
+ dataSource.setConnectionProperties(writeProperties.getConnectionProperties());
try {
- dataSource.setFilters(properties.getFilters());
+ dataSource.setFilters(writeProperties.getFilters());
List filterList=new ArrayList();
filterList.add(wallFilter());
@@ -99,6 +109,50 @@ public DruidDataSource dataSource() {
return dataSource;
}
+ @Bean(name="readDataSource")
+ public List readDataSource(){
+ List list = new ArrayList<>();
+ //不使用的时候 在配置文件中 直接删除掉 也不会报错
+ if(readProperties != null && ArrayUtils.isNotEmpty(readProperties.getUrl())) {
+
+ DruidDataSource readDataSource = new DruidDataSource();
+ readDataSource.setDriverClassName(readProperties.getDriverClassName());
+ try {
+ readDataSource.setFilters(readProperties.getFilters());
+ List filters = new ArrayList<>();
+ filters.add(wallFilter());
+ dataSource().setProxyFilters(filters);
+
+ } catch (SQLException e) {
+ LOGGER.info("读库设置过滤出现异常:{}", e.getMessage());
+ }
+ readDataSource.setMaxWait(readProperties.getMaxWait());
+ readDataSource.setMinIdle(readProperties.getMinIdle());
+ readDataSource.setMaxActive(readProperties.getMaxActive());
+ readDataSource.setInitialSize(readProperties.getInitialSize());
+ readDataSource.setTestOnBorrow(readProperties.getTestOnBorrow());
+ readDataSource.setTestOnReturn(readProperties.getTestOnReturn());
+ readDataSource.setTestWhileIdle(readProperties.getTestWhileIdle());
+ readDataSource.setInitialSize(readProperties.getInitialSize());
+ readDataSource.setValidationQuery(readProperties.getValidationQuery());
+ readDataSource.setConnectionProperties(readProperties.getConnectionProperties());
+ readDataSource.setPoolPreparedStatements(readProperties.getPoolPreparedStatements());
+ readDataSource.setMaxOpenPreparedStatements(readProperties.getMaxOpenPreparedStatements());
+ readDataSource.setMinEvictableIdleTimeMillis(readProperties.getMinEvictableIdleTimeMillis());
+ readDataSource.setTimeBetweenEvictionRunsMillis(readProperties.getTimeBetweenEvictionRunsMillis());
+ list.add(readDataSource);
+ for(int i =0 ; i< readProperties.getUrl().length; i++){
+ DruidDataSource dataSource = readDataSource.cloneDruidDataSource();
+ dataSource.setUrl(readProperties.getUrl()[i]);
+ dataSource.setUsername(readProperties.getUsername()[i]);
+ dataSource.setPassword(readProperties.getPassword()[i]);
+ list.add(dataSource);
+ }
+ }
+ return list;
+ }
+
+
@Bean
public WallConfig wallConfig(){
WallConfig config =new WallConfig();
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyAbstractroutintDataSource.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyAbstractroutintDataSource.java
new file mode 100644
index 0000000..a06bcb4
--- /dev/null
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyAbstractroutintDataSource.java
@@ -0,0 +1,48 @@
+package com.test.eureka.web.client.config;
+
+import com.test.eureka.web.client.enums.DatasourceEnum;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * ======================
+ * Created By User: RXK
+ * Date: 2018/6/6 23:49
+ * Version: V1.0
+ * Description: 继承 Spring 的AbstractRoutingDataSource
+ * 实现 determineCurrentLookupKey 主要是获取当前线程中使用的 是 什么数据源
+ * 自己实现该方法 决定实现的方式
+ *
+ * ======================
+ */
+public class MyAbstractroutintDataSource extends AbstractRoutingDataSource {
+
+ private int readDataSourceSize;
+
+ private AtomicInteger count = new AtomicInteger();
+
+ public MyAbstractroutintDataSource(int readDataSourceSize) {
+ this.readDataSourceSize = readDataSourceSize;
+ }
+
+
+ @Override
+ protected Object determineCurrentLookupKey() {
+
+ //从当前的线程中 获取 LookUpKey
+ String lookUpKey = DataSourceLookUpKeyThreadLocal.getDataSourceLookUpKey();
+
+ //当前环境中 读库的数量 不为0 并且 LookUpKey 不为空
+ //如果当前线程中 保存的是从库或者读库 数据源会有多个 那个轮询的方式 选择对应的数据源
+ if (readDataSourceSize > 0 && StringUtils.isNotBlank(lookUpKey) && lookUpKey.equalsIgnoreCase(DatasourceEnum.READ.name())) {
+ int num = count.getAndAdd(1);
+ int i = num % readDataSourceSize;
+ return new Integer(i);
+ }
+
+ // 返回 主库huozhe或者 写的数据源
+ return DatasourceEnum.WRITE.name();
+ }
+}
diff --git a/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyBatisConfigration.java b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyBatisConfigration.java
new file mode 100644
index 0000000..3a1ace5
--- /dev/null
+++ b/test-eureka-client/src/main/java/com/test/eureka/web/client/config/MyBatisConfigration.java
@@ -0,0 +1,116 @@
+package com.test.eureka.web.client.config;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.ibatis.mapping.DatabaseIdProvider;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
+import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
+import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
+import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+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 org.springframework.util.ObjectUtils;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ======================
+ * Created By User: RXK
+ * Date: 2018/6/6 22:31
+ * Version: V1.0
+ * Description:
+ * ======================
+ */
+@Configuration
+public class MyBatisConfigration extends MybatisAutoConfiguration {
+
+
+ @Autowired
+ private MybatisProperties properties;
+
+ @Autowired
+ private ResourceLoader resourceLoader;
+
+
+ @Resource(name = "dataSource")
+ private DataSource writeDataSource;
+
+ @Resource(name = "readDataSource")
+ private List readDataSource;
+
+ public MyBatisConfigration(MybatisProperties properties, ObjectProvider interceptorsProvider, ResourceLoader resourceLoader, ObjectProvider databaseIdProvider, ObjectProvider> configurationCustomizersProvider) {
+ super(properties, interceptorsProvider, resourceLoader, databaseIdProvider, configurationCustomizersProvider);
+ }
+
+
+ /**
+ * 自定义 SqlSessionFactory 中使用的数据源
+ *
+ * @return :sqlSessionFactory 对象
+ */
+ @Bean
+ @ConditionalOnMissingBean
+ public SqlSessionFactory sqlSessionFactory() throws Exception {
+ SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
+ factory.setDataSource(this.routingDataSource());
+ factory.setVfs(SpringBootVFS.class);
+ if (StringUtils.hasText(this.properties.getConfigLocation())) {
+ factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
+ }
+ org.apache.ibatis.session.Configuration configuration = this.properties.getConfiguration();
+ if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
+ configuration = new org.apache.ibatis.session.Configuration();
+ }
+
+ factory.setConfiguration(configuration);
+ if (this.properties.getConfigurationProperties() != null) {
+ factory.setConfigurationProperties(this.properties.getConfigurationProperties());
+ }
+ if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
+ factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
+ }
+ if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
+ factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
+ }
+ if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
+ factory.setMapperLocations(this.properties.resolveMapperLocations());
+ }
+
+ return factory.getObject();
+ }
+
+
+ @Bean
+ public AbstractRoutingDataSource routingDataSource() {
+ int size = 0;
+
+ if (CollectionUtils.isNotEmpty(readDataSource)) {
+ size = readDataSource.size();
+ }
+
+ MyAbstractroutintDataSource dataSourceProxy = new MyAbstractroutintDataSource(size);
+
+ Map