- 搭建多数据源环境
首先,我们需要在pom.xml中引入所需依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
接着,在application.properties中配置两个数据源的连接信息:
# 第一个数据源
first.datasource.url=jdbc:mysql://localhost:3306/first?useUnicode=true&characterEncoding=utf8&useSSL=false
first.datasource.username=root
first.datasource.password=123456
first.datasource.driver-class-name=com.mysql.jdbc.Driver
# 第二个数据源
second.datasource.url=jdbc:mysql://localhost:3306/second?useUnicode=true&characterEncoding=utf8&useSSL=false
second.datasource.username=root
second.datasource.password=123456
second.datasource.driver-class-name=com.mysql.jdbc.Driver
在各自配置的基础上,我们需要通过@ConfigurationProperties注解将两个数据源配置到不同的DataSource实例中,并且注入到Spring容器中:
@Configuration
public class DataSourceConfig {
@Bean(name = "firstDataSource")
@Qualifier("firstDataSource")
@ConfigurationProperties(prefix = "first.datasource")
public DataSource firstDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean(name = "secondDataSource")
@Qualifier("secondDataSource")
@Primary
@ConfigurationProperties(prefix = "second.datasource")
public DataSource secondDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean(name = "dynamicDataSource")
public DynamicDataSource dataSource(@Qualifier("firstDataSource") DataSource firstDataSource,
@Qualifier("secondDataSource") DataSource secondDataSource) {
Map<Object, Object> targetDataSource = new HashMap<>();
targetDataSource.put(DataSourceType.FIRST, firstDataSource);
targetDataSource.put(DataSourceType.SECOND, secondDataSource);
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSource);
dataSource.setDefaultTargetDataSource(firstDataSource);
return dataSource;
}
@Bean(name = "jdbcTemplate")
public JdbcTemplate jdbcTemplate(
@Qualifier("dynamicDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
- 添加自定义注解
我们自己定义了一个注解@DataSource,用于注解到数据访问层的接口上:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface DataSource {
DataSourceType value() default DataSourceType.FIRST;
}
@DataSource中的DataSourceType是枚举类型,用于标识不同的数据源:
public enum DataSourceType {
FIRST,
SECOND
}
- AOP切面
最后,在AOP切面中,获取@DataSource注解的值,从而动态切换数据源:
@Component
@Aspect
public class DataSourceAspect {
@Pointcut("@annotation(com.example.demo.annotation.DataSource) " +
"|| @within(com.example.demo.annotation.DataSource)")
public void pointCut() {
}
@Around("pointCut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Class<?> targetClass = joinPoint.getTarget().getClass();
// 先优先判断类上是否有@DataSource注解
DataSourceType dsType = targetClass.isAnnotationPresent(DataSource.class) ?
targetClass.getAnnotation(DataSource.class).value() : DataSourceType.FIRST;
// 再判断方法上是否有@DataSource注解
Method method = signature.getMethod();
if (method.isAnnotationPresent(DataSource.class)) {
DataSource annotation = method.getAnnotation(DataSource.class);
dsType = annotation.value();
}
DataSourceContextHolder.setDataSourceType(dsType);
try {
return joinPoint.proceed();
} finally {
DataSourceContextHolder.clearDataSourceType();
}
}
}
- 示例
示例1:在service层的方法上添加自定义注解@DataSource,并指定使用第二个数据源。即:
@DataSource(DataSourceType.SECOND)
public int updateSecond() {
// ...
}
示例2:在数据访问层接口上添加自定义注解@DataSource,并指定使用第一个数据源。即:
@DataSource(DataSourceType.FIRST)
public interface FirstMapper {
// ...
}
以上就是SpringBoot利用自定义注解实现多数据源的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot利用自定义注解实现多数据源 - Python技术站