1. 自定义注解
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetSource {
String value() default "ds1";
}
2. 创建DynamicDataSourceHolder类,存在数据源名称
public class DynamicDataSourceHolder {
private static ThreadLocal<String> local = new ThreadLocal<>();
public static String getDs() {
return local.get();
}
public static ThreadLocal getLocal(){
return local;
}
}
3. 创建DynamicDataSource类,获取数据源名称
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
String ds = DynamicDataSourceHolder.getDs();
System.out.println("=========选择的数据源:" + ds);
return ds;
}
}
4. 创建切面类AspectDs,拦截自定义的注解
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(-1)
public class AspectDs {
@Before(value = "@annotation(targetSource)")
public void dataSource(TargetSource targetSource) {
String value = targetSource.value();
if(value != null && !"".equals(value)) {
DynamicDataSourceHolder.getLocal().set(value);
System.out.println("========AspectDs:"+value);
} else {
System.out.println("========AspectDs:ds1");
DynamicDataSourceHolder.getLocal().set("ds1");
}
}
}
5. 创建数据源配置类DataSourceConfiguration
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
@Configuration
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
@Value("${db.driverClassName}")
private String driverClass;
@Value("${db.url}")
private String jdbcUrl;
@Value("${db.url2}")
private String jdbcUrl2;
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
public DataSource getDs1(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClass);
druidDataSource.setUrl(jdbcUrl);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setMaxActive(2);
druidDataSource.setInitialSize(2);
druidDataSource.setTimeBetweenConnectErrorMillis(60000);
druidDataSource.setMinEvictableIdleTimeMillis(300000);
druidDataSource.setValidationQuery("SELECT 1 FROM DUAL");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
druidDataSource.setPoolPreparedStatements(true);
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
try {
druidDataSource.setFilters("stat,wall");
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
public DataSource getDs2(){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setDriverClassName(driverClass);
druidDataSource.setUrl(jdbcUrl2);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setMaxActive(2);
druidDataSource.setInitialSize(2);
druidDataSource.setTimeBetweenConnectErrorMillis(60000);
druidDataSource.setMinEvictableIdleTimeMillis(300000);
druidDataSource.setValidationQuery("SELECT 1 FROM DUAL");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
druidDataSource.setPoolPreparedStatements(true);
druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
try {
druidDataSource.setFilters("stat,wall");
} catch (SQLException e) {
e.printStackTrace();
}
return druidDataSource;
}
@Bean
public DataSource dynamicDataSource() {
Map<Object, Object> targetDataSources = new HashMap<>();
DataSource ds1 = getDs1();
DataSource ds2 = getDs2();
targetDataSources.put("ds1", ds1);
targetDataSources.put("ds2", ds2);
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(ds1);
return dynamicDataSource;
}
}
6. 在方法上添加@TargetSource
- 使用ds2数据源,aop会自动拦截到此注解并使用ds2查询数据
@TargetSource(value = "ds2")
public User findUserById(String id) {
return (User) this.getObjectById(User.class, id);
}