springBoot学习---从SSM的动态数据源到SpringBoot的动态数据源的实现方案二

和方案一区别:

spring:
  datasource:
    primary:
      url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8
      username: zhangzx
      password: 123
      driverClassName: com.mysql.cj.jdbc.Driver
    slave1:
      url: jdbc:mysql://127.0.0.1:3306/slave1?characterEncoding=utf-8
      username: zhangzx
      password: 123
      driverClassName: com.mysql.cj.jdbc.Driver
    names: primary,slave1



package com.itw.learn;

import com.itw.learn.config.DynamicDataSourceRegister;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;


import java.util.Arrays;


@MapperScan("com.itw.learn.dao")
@SpringBootApplication
//需要导入这个注册类,初始化config对象之后,初始化我们的import对象
@Import(DynamicDataSourceRegister.class)
public class MyAppDemo {

	public static void main(String[] args) {
		ApplicationContext ctx =  SpringApplication.run(MyAppDemo.class, args);
	}
	@Bean
	public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
		// 目的是
		return args -> {
			System.out.println("来看看 SpringBoot 默认为我们提供的 Bean:");
			String[] beanNames = ctx.getBeanDefinitionNames();
			Arrays.stream(beanNames)
					.filter(t->t.equals("PrimaryDatasource"))
					.forEach(System.out::println);
			//Arrays.sort(beanNames);
			//Arrays.stream(beanNames).forEach(System.out::println);
		};
	}
}

数据源 注册类:

package com.itw.learn.config;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;

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

public class DynamicDataSourceRegister implements  ImportBeanDefinitionRegistrar,EnvironmentAware , ResourceLoaderAware {

	private Environment environment;

	private ResourceLoader resourceLoader;

	//默认数据源
	private DataSource defaultDataSource;
	//所有的数据源
	private Map<String, DataSource> targetDataSources = new HashMap<>();

	void initDefaultDataSource(){
		defaultDataSource = DataSourceBuilder
				.create()
				.driverClassName(environment.getProperty("spring.datasource.primary.driver-class-name"))
				.url(environment.getProperty("spring.datasource.primary.url"))
				.username( environment.getProperty("spring.datasource.primary.username"))
				.password(environment.getProperty("spring.datasource.primary.password"))
				.build();
	}

	void initTargetDataSources() {
		// 读取配置文件获取全部数据源
		String dsPrefixs = environment.getProperty("spring.datasource.names");
		for (String dsPrefix : dsPrefixs.split(",")) {
			// 多个数据源
			DataSource ds =DataSourceBuilder
					.create()
					.driverClassName(environment.getProperty("spring.datasource." + dsPrefix + ".driver-class-name"))
					.url(environment.getProperty("spring.datasource." + dsPrefix + ".url"))
					.username( environment.getProperty("spring.datasource." + dsPrefix + ".username"))
					.password(environment.getProperty("spring.datasource." + dsPrefix + ".password"))
					.build();
			targetDataSources.put(dsPrefix,ds);
		}
	}

	@Override
	public void setEnvironment(Environment environment) {
		this.environment = environment;
		initDefaultDataSource();
		initTargetDataSources();
	}

	@Override
	public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
		//创建DynamicDataSource
		GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
		beanDefinition.setBeanClass(DynamicDataSource.class);
		beanDefinition.setSynthetic(true);
		MutablePropertyValues mpv = beanDefinition.getPropertyValues();
		mpv.addPropertyValue("defaultTargetDataSource", defaultDataSource);
		mpv.addPropertyValue("targetDataSources", targetDataSources);
		//注册 - BeanDefinitionRegistry
		beanDefinitionRegistry.registerBeanDefinition("dataSource", beanDefinition);
	}
        //这个ResourceLoaderAware接口的实现是 不需要的,可以去掉
	@Override
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

}

该方案的优点:

很明显,只是做了数据源的注入,所以我们还是按往常一样使用mybatis就可以了,不用像方案一,需要将扫描xml的位置在代码中编写。

其次:我们如果注册多个数据源,只需要修改配置文件即可,代码是不需要修改的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值