Spring Boot Multi-Data source configuration

Source: Internet
Author: User
Tags connection pooling

The following Java class is already written to dynamically create multi-DataSource code based on the configuration file, the principle is also very simple, is to read the configuration file, based on the number of data sources configured in the configuration file, dynamically create DataSource and register to spring.

The code is as follows:

Package org.springboot.sample.config;Import Java.util.HashMap;Import Java.util.Map;Import Java.util.Map.Entry;Import Javax.sql.DataSource;Import Org.slf4j.Logger;Import Org.slf4j.LoggerFactory;Import org.springframework.beans.BeansException;Import org.springframework.beans.MutablePropertyValues;Import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;Import org.springframework.beans.factory.config.BeanDefinition;Import Org.springframework.beans.factory.config.BeanDefinitionHolder;Import Org.springframework.beans.factory.config.ConfigurableListableBeanFactory;Import Org.springframework.beans.factory.support.BeanDefinitionReaderUtils;Import Org.springframework.beans.factory.support.BeanDefinitionRegistry;Import Org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;Import Org.springframework.beans.factory.support.BeanNameGenerator;Import Org.springframework.boot.bind.RelaxedPropertyResolver;Import Org.springframework.context.EnvironmentAware;Import Org.springframework.context.annotation.AnnotationBeanNameGenerator;Import Org.springframework.context.annotation.AnnotationConfigUtils;Import Org.springframework.context.annotation.AnnotationScopeMetadataResolver;Import org.springframework.context.annotation.Configuration;Import Org.springframework.context.annotation.ScopeMetadata;Import Org.springframework.context.annotation.ScopeMetadataResolver;Import org.springframework.core.env.Environment;/** * Dynamically create multiple data sources to register in spring **/@ConfigurationPublicClassMultipledatasourcebeandefinitionregistrypostprocessorImplementsBeandefinitionregistrypostprocessor,Environmentaware {PrivateStaticFinal Logger Logger = loggerfactory. GetLogger (Multipledatasourcebeandefinitionregistrypostprocessor.class);Use this default value if the data source type is not specified in the configuration filePrivateStaticFinal Object Datasource_type_default ="Org.apache.tomcat.jdbc.pool.DataSource";private static final Object Datasource_type_default = "Com.zaxxer.hikari.HikariDataSource";Private Scopemetadataresolver Scopemetadataresolver =New Annotationscopemetadataresolver ();Private Beannamegenerator Beannamegenerator =New Annotationbeannamegenerator ();Collection of storage datasource configurations, models <dataSourceName,dataSourceMap>Private map<string, map<string, object>> datasourcemap =New Hashmap<> ();@OverridePublicvoidPostprocessbeanfactory (Configurablelistablebeanfactory beanfactory)Throws Beansexception {Logger.info ("Invoke metho postprocessbeanfactory"); Beanfactory.getbeandefinition ("DataSource"). Setprimary (true); beandefinition BD =Null map<string, object> DsMap =NullFor (entry<string, map<string, object>> Entry:dataSourceMap.entrySet ()) {BD = Beanfactory.getbeandefinition (Entry.getkey ()); Mutablepropertyvalues MPV = bd.getpropertyvalues (); DsMap = Entry.getvalue (); Mpv.addpropertyvalue ("Driverclassname", Dsmap.get ("url")); Mpv.addpropertyvalue ("url", Dsmap.get ("url")); Mpv.addpropertyvalue ("Username", Dsmap.get ("username")); Mpv.addpropertyvalue ("Password", Dsmap.get ("Password")); } }@SuppressWarnings ("Unchecked")@OverridePublicvoidPostprocessbeandefinitionregistry (Beandefinitionregistry Registry)Throws Beansexception {Logger.info ("Invoke metho postprocessbeandefinitionregistry");try {if (!datasourcemap.isempty ()) {For (entry<string, map<string, object>> Entry:dataSourceMap.entrySet ()) {Object type = Entry.getvalue (). GE T"Type");if (type = =NULL) type = Datasource_type_default;Default DataSource Registerbean (registry, Entry.getkey (), (class<? extends datasource>) Class.forName ( Type.tostring ())); } } }catch (ClassNotFoundException e) {e.printstacktrace ();}}/** * Register Bean to Spring * *@param Registry *@param name *@param beanclass*/PrivatevoidRegisterbean (Beandefinitionregistry Registry, String name, class<?> beanclass) {annotatedgenericbeandefinition ABD =New Annotatedgenericbeandefinition (Beanclass); Scopemetadata Scopemetadata =This.scopeMetadataResolver.resolveScopeMetadata (ABD); Abd.setscope (Scopemetadata.getscopename ());can automatically generate name String Beanname = (Name! =Null? Name:This.beanNameGenerator.generateBeanName (Abd, Registry)); Annotationconfigutils.processcommondefinitionannotations (ABD); Beandefinitionholder Definitionholder =new Beandefinitionholder (Abd, beanname); Beandefinitionreaderutils.registerbeandefinition (Definitionholder, registry); } /** * Load multi-Data source configuration */ @Override  Public void setenvironment (Environment env) { Relaxedpropertyresolver propertyresolver = new relaxedpropertyresolver (env, " Custom.datasource "); String Dsprefixs = propertyresolver.getproperty ( "names"); for (String dsPrefix:dsPrefixs.split (//Multiple data Sources map<string, object> dsMap = propertyresolver.getsubproperties (dsprefix + "); Datasourcemap.put (Dsprefix, DSMAP); } }}

Add the Java file directly to the project, without any other code coupling, simply a class.

Look again at the method of configuring a multiple data source in a configuration file:

# Primary data source, default spring. DataSource. type=Com. zaxxer. Hikari. Hikaridatasourcespring. DataSource. driver-class-name=Com. mysql. jdbc. Driverspring. DataSource. Url=jdbc:mysql://localhost:3306/testspring. DataSource. username=rootspring. DataSource. password=123456# More Data Sources custom. DataSource. names=ds1,ds2,ds3custom. DataSource. DS1. type=Com. zaxxer. Hikari. Hikaridatasourcecustom. DataSource. DS1. driver-class-name=Com. mysql. jdbc. Drivercustom. DataSource. DS1. Url=jdbc:mysql://localhost:3306/testcustom. DataSource. DS1. username=rootcustom. DataSource. DS1. password=123456custom. DataSource. ds2. type=Com. zaxxer. Hikari. Hikaridatasourcecustom. DataSource. ds2. driver-class-name=Com. mysql. jdbc. Drivercustom. DataSource. ds2. Url=jdbc:mysql://localhost:3306/testcustom. DataSource. ds2. username=rootcustom. DataSource. ds2. password=123456custom. DataSource. DS3. type=Com. zaxxer. Hikari. Hikaridatasourcecustom. DataSource. DS3. driver-class-name=Com. mysql. jdbc. Drivercustom. DataSource. DS3. Url=jdbc:mysql://localhost:3306/testcustom. DataSource. DS3. username=rootcustom. DataSource. DS3. password=123456# The following supplemental settings for connection pooling are applied to all of the above data sources in spring. DataSource. maximum-pool-size=100spring. DataSource. max-idle=10spring.datasource.max-wait= 10000spring.datasource .min-idle=5spring.initial-size=5spring .datasource.validation-query=select 1spring.datasource.datasource.datasource18800       

The configuration file consists of 1 main data sources and multiple data sources, where the main data source in spring Beanname default to DataSource, and several data sources of the Beanname sub-package is: DS1, DS2, DS3, we look at the configuration of the rules, presumably do not say much.
Where the type attribute of DataSource can be specified to the data source we need, the default is not specified: Org.apache.tomcat.jdbc.pool.DataSource

Of course you can also configure these data sources into the primary DataSource database, and then read the database to generate multiple data sources. Of course, the necessity of doing so is not big, the data source will often change.

You need to specify a name where you want to apply DataSource, such as:

// 方法参数注入方式public void testDataSource(@Qualifier("ds1") DataSource myDataSource, @Qualifier("dataSource") DataSource dataSource) {}

Or

// 类成员属性注入方式@Autowired@Qualifier("ds1")private DataSource dataSource1;@Resource(name = "ds2")private DataSource dataSource2;

The code shared in this article can be used directly, you can adjust according to your own needs.

However, we do not necessarily need to use DataSource directly in the project, everyone is accustomed to using the JDBC JdbcTemplate, MyBatis sqlsessiontemplate, Or, take MyBatis as an example, direct dynamic proxy to the Mapper interface.

So how do we do a fully dynamic data source so that we can specify different data sources for different methods of the same Java class, respectively?

Spring Boot Multi-Data source configuration

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.