DataSourceConfiguration.java 3.68 KB
package com.diligrp.boss.shared.datasource;

import com.zaxxer.hikari.HikariDataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Aspect
@Configuration
public class DataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSourceProperties masterProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource masterDataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        DataSourceProperties properties = masterProperties();
        dataSource.setDriverClassName(properties.determineDriverClassName());
        dataSource.setJdbcUrl(properties.determineUrl());
        dataSource.setUsername(properties.determineUsername());
        dataSource.setPassword(properties.determinePassword());
        return dataSource;
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSourceProperties slaveProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.slave.hikari")
    public DataSource salveDataSource() {
        HikariDataSource dataSource = new HikariDataSource();
        DataSourceProperties properties = slaveProperties();
        dataSource.setDriverClassName(properties.determineDriverClassName());
        dataSource.setJdbcUrl(properties.determineUrl());
        dataSource.setUsername(properties.determineUsername());
        dataSource.setPassword(properties.determinePassword());
        return dataSource;
    }

    @Bean
    @Primary
    public DataSource dynamicDataSource() {
        Map<Object, Object> datasourceMap = new HashMap<>();
        datasourceMap.put(DataSourceName.MASTER, masterDataSource());
        datasourceMap.put(DataSourceName.SLAVE, salveDataSource());

        MultipleDataSource multipleDataSource = new MultipleDataSource();
        multipleDataSource.setTargetDataSources(datasourceMap);
        multipleDataSource.setDefaultTargetDataSource(masterDataSource());
        return multipleDataSource;
    }

    @Pointcut(value = "@annotation(com.diligrp.boss.shared.datasource.DataSourceOption)")
    public void dataSourcePointCut(){
    }

    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        DataSourceName name = getMetadata(joinPoint).value();
        try{
            DataSourceNameContext.setDataSourceName(name);
            return joinPoint.proceed();
        }finally {
            DataSourceNameContext.removeDataSourceName();
        }
    }

    private DataSourceOption getMetadata(ProceedingJoinPoint joinPoint) {
        Class<?> targetClass = joinPoint.getTarget().getClass();
        DataSourceOption annotation = targetClass.getAnnotation(DataSourceOption.class);
        if (Objects.nonNull(annotation)) {
            return annotation;
        } else {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            return signature.getMethod().getAnnotation(DataSourceOption.class);
        }
    }
}