Dynamically add a data source SpringBoot runtime

This program applies to solve dynamically add data sources springboot project is running, non-static switch multiple data sources! ! !

First, multiple data source scenarios:

1. Profile Configuration multiple data sources, such as the default data source: master, data source 1: salve1 ..., dynamic run-time data source configured to switch (master, salve1 each switch), can not be added dynamically at run-time profile not configured data source.

Configuring a default data source, dynamically add a new data source runtime (the present scenario for this blog)

Second, the solution:

Spring provides for dynamic routing AbstractRoutingDataSource data source, a first scenario and override inherited class AbstractRoutingDataSource its protected abstract Object determineCurrentLookupKey () can;
and the second scenario we direct overwrite method may be protected DataSource determineTargetDataSource. Principle can look AbstractRoutingDataSource the corresponding source code, it is relatively simple, not repeat them.
Directly on dry goods:

import com.fizz.utils.spring.SpringUtils;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

    private static final ThreadLocal<DataSource> dataSource = ThreadLocal.withInitial(() -> (DataSource) SpringUtils.getBean("defaultDataSource"));

    public static void setDataSource(DataSource dataSource) {
        DynamicDataSource.dataSource.set(dataSource);
    }

    public static DataSource getDataSource() {
        return DynamicDataSource.dataSource.get();
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return null;
    }

    @Override
    protected DataSource determineTargetDataSource() {
        return getDataSource();
    }

    public static void clear() {
        DynamicDataSource.dataSource.remove();
    }
}

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
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;

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource.druid")
    public DataSource defaultDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public DynamicDataSource dataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        dynamicDataSource.setTargetDataSources(new HashMap<>());
        return dynamicDataSource;
    }
}

When using the direct call DynamicDataSource.setDataSource (DataSource dataSource) method may be used after call DynamicDataSource.clear () memory leaks and reset default data source.

Attach Usage Details:

        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl("jdbc:mysql://localhost:3306/sys?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC&useAffectedRows=true");
        druidDataSource.setUsername("root");
        druidDataSource.setPassword("root");
        DynamicDataSource.setDataSource(druidDataSource);
        此时数据源已切换到druidDataSource ,调用自己的业务方法即可。
        使用完后调用DynamicDataSource.clear();重置为默认数据源。

Attach tools:

import lombok.Getter;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public final class SpringUtils implements ApplicationContextAware {

@Getter
private static ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    if (SpringUtils.applicationContext == null) {
        SpringUtils.applicationContext = applicationContext;
    }
}

public static <T> T getBean(Class<T> clazz) {
    return SpringUtils.applicationContext.getBean(clazz);
}

public static Object getBean(String name) {
    return SpringUtils.applicationContext.getBean(name);
}

public static String getProperty(String key) {
    return SpringUtils.applicationContext.getEnvironment().getProperty(key);
}

}

Guess you like

Origin www.cnblogs.com/tswhq/p/11668078.html