1 package com.backstage.lddome.config;
2
3 import com.backstage.lddome.datasource.DynamicDataSource;
4 import org.apache.ibatis.session.SqlSessionFactory;
5 import org.mybatis.spring.SqlSessionFactoryBean;
6 import org.springframework.beans.factory.annotation.Qualifier;
7 import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
8 import org.springframework.boot.context.properties.ConfigurationProperties;
9 import org.springframework.context.annotation.Bean;
10 import org.springframework.context.annotation.Configuration;
11 import org.springframework.context.annotation.Primary;
12 import org.springframework.core.io.Resource;
13 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
14 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
15 import org.springframework.transaction.PlatformTransactionManager;
16 import sun.security.krb5.Config;
17
18 import javax.sql.DataSource;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 /**
23 * 多数据源配置类
24 * Created by pure on 2018-05-06.
25 */
26 @Configuration
27 public class DataSourceConfig {
28 //数据源1
29 @Bean(name = "datasource1")
30 @ConfigurationProperties(prefix = "spring.datasource.db1") // application.properteis中对应属性的前缀
31 public DataSource dataSource1() {
32 return DataSourceBuilder.create().build();
33 }
34
35 //数据源2
36 @Bean(name = "datasource2")
37 @ConfigurationProperties(prefix = "spring.datasource.db2") // application.properteis中对应属性的前缀
38 public DataSource dataSource2() {
39 return DataSourceBuilder.create().build();
40 }
41
42 /**
43 * 动态数据源: 通过AOP在不同数据源之间动态切换
44 *
45 * @return
46 */
47 @Primary
48 @Bean(name = "dynamicDataSource")
49 public DataSource dynamicDataSource() {
50 DynamicDataSource dynamicDataSource = new DynamicDataSource();
51 // 默认数据源
52 dynamicDataSource.setDefaultTargetDataSource(dataSource1());
53 // 配置多数据源
54 Map<Object, Object> dsMap = new HashMap();
55 dsMap.put("datasource1", dataSource1());
56 dsMap.put("datasource2", dataSource2());
57
58 dynamicDataSource.setTargetDataSources(dsMap);
59 return dynamicDataSource;
60 }
61
62 /**
63 * 配置@Transactional注解事物
64 *
65 * @return
66 */
67 @Bean
68 public PlatformTransactionManager transactionManager() {
69 return new DataSourceTransactionManager(dynamicDataSource());
70 }
71 }
1 package com.backstage.lddome.aspect;
2
3 import com.backstage.lddome.datasource.DS;
4 import com.backstage.lddome.datasource.DataSourceContextHolder;
5 import org.aspectj.lang.JoinPoint;
6 import org.aspectj.lang.annotation.After;
7 import org.aspectj.lang.annotation.Aspect;
8 import org.aspectj.lang.annotation.Before;
9 import org.aspectj.lang.reflect.MethodSignature;
10 import org.springframework.stereotype.Component;
11
12 import java.io.*;
13 import java.lang.reflect.Method;
14 import java.net.URL;
15 import java.net.URLConnection;
16
17 /**
18 * 自定义注解 + AOP的方式实现数据源动态切换。
19 * Created by pure on 2018-05-06.
20 */
21 @Aspect
22 @Component
23 public class DynamicDataSourceAspect {
24
25 @Before("@annotation(ds)")
26 public void beforeSwitchDS(JoinPoint point, DS ds) {
27 //获得当前访问的class
28 Class<?> className = point.getTarget().getClass();
29 //获得访问的方法名
30 String methodName = point.getSignature().getName();
31 //得到方法的参数的类型
32 Class[] argClass = ((MethodSignature) point.getSignature()).getParameterTypes();
33 String dataSource = DataSourceContextHolder.DEFAULT_DS;
34 try {
35 // 得到访问的方法对象
36 Method method = className.getMethod(methodName, argClass);
37 // 判断是否存在@DS注解
38 if (method.isAnnotationPresent(DS.class)) {
39 DS annotation = method.getAnnotation(DS.class);
40 // 取出注解中的数据源名
41 dataSource = annotation.value();
42 }
43 } catch (Exception e) {
44 e.printStackTrace();
45 }
46 // 切换数据源
47 DataSourceContextHolder.setDB(dataSource);
48 }
49
50 @After("@annotation(ds)")
51 public void afterSwitchDS(JoinPoint point, DS ds) {
52 DataSourceContextHolder.clearDB();
53 }
54
55
56 public static void main(String[] args) {
57
58 String path = "f:\\haha";
59 try {
60 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
61 URL url = new URL("http://imgs.jinxiaoersh.com/1576219511646f0d52580401241b5aed3ccaae3e72880.png");
62 URLConnection urlConnection = url.openConnection();
63 InputStream inputStream = urlConnection.getInputStream();
64
65
66 String file = url.getFile();
67 System.out.println(file);
68 // FileInputStream fileInputStream = new FileInputStream(url);
69 int len = -1;
70 //循环读取
71 byte[] b = new byte[1024];
72 while ((len = inputStream.read(b)) != -1) {
73 byteArrayOutputStream.write(b, 0, len);
74 }
75 //返回byteArrayOutputStream数组
76 byte[] bytes = byteArrayOutputStream.toByteArray();
77 new DataOutputStream(new FileOutputStream(path)).write(bytes);
78 } catch (Exception e) {
79 System.out.println(e);
80 }
81
82
83 }
84 }
1 package com.backstage.lddome.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 /**
9 * 自定义注解
10 */
11 @Retention(RetentionPolicy.RUNTIME)
12 @Target({ElementType.METHOD})
13 public @interface DS {
14 String value() default "datasource1";
15 }
1 package com.backstage.lddome.datasource;
2
3 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
4 import org.springframework.stereotype.Component;
5
6 /**
7 * Created by pure on 2018-05-06.
8 */
9 public class DynamicDataSource extends AbstractRoutingDataSource {
10 @Override
11 protected Object determineCurrentLookupKey() {
12 System.out.println("数据源为" + DataSourceContextHolder.getDB());
13 return DataSourceContextHolder.getDB();
14 }
15 }
1 package com.backstage.lddome.datasource;
2
3 import java.io.*;
4
5 /**
6 * Created by pure on 2018-05-06.
7 */
8 public class DataSourceContextHolder {
9 /**
10 * 默认数据源
11 */
12 public static final String DEFAULT_DS = "datasource1";
13 private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
14
15 // 设置数据源名
16 public static void setDB(String dbType) {
17 contextHolder.set(dbType);
18 }
19
20 // 获取数据源名
21 public static String getDB() {
22 return (contextHolder.get());
23 }
24
25 // 清除数据源名
26 public static void clearDB() {
27 contextHolder.remove();
28 }
29
30
31 public static Object copy(Object orig) throws IOException, ClassNotFoundException {
32 Object obj = null;
33 // Write the object out to a byte array
34 ByteArrayOutputStream bos = new ByteArrayOutputStream();
35 ObjectOutputStream out = new ObjectOutputStream(bos);
36 out.writeObject(orig);
37 out.flush();
38 out.close();
39
40 // Make an input stream from the byte array and read
41 // a copy of the object back in.
42 ObjectInputStream in = new ObjectInputStream(
43 new ByteArrayInputStream(bos.toByteArray()));
44 obj = in.readObject();
45
46 return obj;
47 }
48 }