动态数据源

 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 }

 

posted @ 2020-12-16 20:09  不知无畏  阅读(243)  评论(0)    收藏  举报