Spring configures multiple data sources (case)

Source: Internet
Author: User

*.properties configuration:

<!--data Connection configuration---

Jdbc.type=mysql
Jdbc.driver=com.mysql.jdbc.driver
jdbc.url=jdbc:mysql://localhost:3066/qshop?useunicode=true&amp;characterencoding=utf-8&amp; Usefastdateparsing=false&amp;allowmultiqueries=true&amp;servertimezone=gmt%2b8
Jdbc.username=xxxxx
Jdbc.password=xxxx

<!--data Connection configuration two--

Merchant.jdbc.type=mysql
Merchant.jdbc.driver=com.mysql.jdbc.driver
Merchant.jdbc.url=jdbc:mysql://localhost:3066/qshop_merchant?useunicode=true&amp;characterencoding=utf-8 &amp;usefastdateparsing=false&amp;allowmultiqueries=true&amp;servertimezone=gmt%2b8
Merchant.jdbc.username=xxxx
Merchant.jdbc.password=xxxx

Spring-application.xml configuration:

<!--data source, data source configuration, using Druid database connection pool--
<bean id= "DataSource" class= "Com.alibaba.druid.pool.DruidDataSource" init-method= "Init" destroy-method= "Close" >
<!--data source driver class is not writable, Druid is automatically identified by URL Driverclass-
<property name= "Driverclassname" value= "${jdbc.driver}"/>

<!--basic property URL, user, password--
<property name= "url" value= "${jdbc.url}"/>
<property name= "username" value= "${jdbc.username}"/>
<property name= "Password" value= "${jdbc.password}"/>

<!--configuration initialization size, MIN, max--
<property name= "InitialSize" value= "${jdbc.pool.init}"/>
<property name= "Minidle" value= "${jdbc.pool.minidle}"/>
<property name= "maxactive" value= "${jdbc.pool.maxactive}"/>

<!--configuration Gets the time that the connection waits timeout--
<property name= "maxwait" value= "60000"/>

< how long!--configuration interval to detect idle connections that need to be closed, in milliseconds-and
<property name= "Timebetweenevictionrunsmillis" value= "60000"/>

<!--Configure the minimum time for a connection to survive in a pool, in milliseconds--
<property name= "Minevictableidletimemillis" value= "300000"/>

<property name= "Validationquery" value= "${jdbc.testsql}"/>
<property name= "Testwhileidle" value= "true"/>
<property name= "Testonborrow" value= "false"/>
<property name= "Testonreturn" value= "false"/>

<!--open Pscache and specify the size of Pscache on each connection (Oracle uses)
<property name= "Poolpreparedstatements" value= "true"/>
<property name= "maxpoolpreparedstatementperconnectionsize" value= "/>"--

<!--configuration monitoring statistics intercept filters--
<property name= "Filters" value= "stat"/>
</bean>


<!--data source two, business data source configuration, using Druid database connection pool--
<bean id= "Merchantdatasource" class= "Com.alibaba.druid.pool.DruidDataSource" init-method= "Init" destroy-method= "Close" >
<!--data source driver class is not writable, Druid is automatically identified by URL Driverclass-
<property name= "Driverclassname" value= "${merchant.jdbc.driver}"/>

<!--basic property URL, user, password--
<property name= "url" value= "${merchant.jdbc.url}"/>
<property name= "username" value= "${merchant.jdbc.username}"/>
<property name= "Password" value= "${merchant.jdbc.password}"/>

<!--configuration initialization size, MIN, max--
<property name= "InitialSize" value= "${jdbc.pool.init}"/>
<property name= "Minidle" value= "${jdbc.pool.minidle}"/>
<property name= "maxactive" value= "${jdbc.pool.maxactive}"/>

<!--configuration Gets the time that the connection waits timeout--
<property name= "maxwait" value= "60000"/>

< how long!--configuration interval to detect idle connections that need to be closed, in milliseconds-and
<property name= "Timebetweenevictionrunsmillis" value= "60000"/>

<!--Configure the minimum time for a connection to survive in a pool, in milliseconds--
<property name= "Minevictableidletimemillis" value= "300000"/>

<property name= "Validationquery" value= "${jdbc.testsql}"/>
<property name= "Testwhileidle" value= "true"/>
<property name= "Testonborrow" value= "false"/>
<property name= "Testonreturn" value= "false"/>

<!--open Pscache and specify the size of Pscache on each connection (Oracle uses)
<property name= "Poolpreparedstatements" value= "true"/>
<property name= "maxpoolpreparedstatementperconnectionsize" value= "/>"--

<!--configuration monitoring statistics intercept filters--
<property name= "Filters" value= "stat"/>
</bean>

<!--configuring Dynamic Data Sources--

<bean id= "Dynamicdatasource" class= "Com.yryz.qshop.modules.dynamiclink.DynamicDataSource" >

<property name= "Targetdatasources" >
<map key-type= "Java.lang.String" >
<!--Specify the LookupKey and the corresponding data source
<entry key= "DataSource" value-ref= "DataSource" ></entry>
<entry key= "Merchantdatasource" value-ref= "Merchantdatasource" ></entry>
</map>
</property>
<!--Here you can specify the default data source {It is best not to specify, there is a pit}--> after the specified
<!--<property name= "Defaulttargetdatasource" ref= "DataSource"/>--
</bean>

<bean id= "Datasourceaspect" class= "Com.yryz.qshop.modules.dynamiclink.aspect.DataSourceAspect"/>
<aop:config>
<aop:aspect ref= "Datasourceaspect" >
<aop:pointcut id= "datasourcepointcut" expression= "Execution (* com.yryz.qshop.modules.merchantremote.service.*. *(..))" />
<aop:before pointcut-ref= "Datasourcepointcut" method= "intercept"/>
</aop:aspect>
</aop:config>

Dynamic Data Source classes:

Dynamicdatasourceholder.java

Package com.yryz.qshop.modules.dynamiclink;

public class Dynamicdatasourceholder {

/**
* Note: The data source ID is saved in the thread variable to avoid interfering with the data source when the multi-threading operation
*/
private static final threadlocal<string> Thread_data_source = new threadlocal<string> ();

public static String Getdatasource () {
return Thread_data_source.get ();
}

public static void Setdatasource (String dataSource) {
Thread_data_source.set (DataSource);
}

public static void Cleardatasource () {
Thread_data_source.remove ();
}

}

Dynamicdatasource.java

Package com.yryz.qshop.modules.dynamiclink;

Import Org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class Dynamicdatasource extends abstractroutingdatasource{

@Override
Protected Object Determinecurrentlookupkey () {
Get the data source identity from a custom location
return Dynamicdatasourceholder.getdatasource ();
}

}

DataSource notes:

Package com.yryz.qshop.modules.dynamiclink.inter;

Import Java.lang.annotation.ElementType;
Import java.lang.annotation.Retention;
Import Java.lang.annotation.RetentionPolicy;
Import Java.lang.annotation.Target;

@Target ({Elementtype.type,elementtype.method})
@Retention (Retentionpolicy.runtime)
Public @interface DataSource {
String value ();
}

Interception device

Datasourceaspect.java

Package com.yryz.qshop.modules.dynamiclink.aspect;

Import Java.lang.reflect.Method;

Import Org.aspectj.lang.JoinPoint;
Import Org.aspectj.lang.reflect.MethodSignature;

Import Com.yryz.qshop.modules.dynamiclink.DynamicDataSourceHolder;
Import Com.yryz.qshop.modules.dynamiclink.inter.DataSource;

public class Datasourceaspect {

/**
* Intercepts the target method, gets the data source identity specified by @datasource, sets it to the thread store to switch the data source
*
* @param point
* @throws Exception
*/
P ublic void Intercept (Joinpoint point) throws Exception {
Class<?> target = Point.gettarget (). GetClass ();
Methodsignature signature = (methodsignature) point.getsignature ();
//Use annotations of the target type by default, and if not, use the annotations that implement the interface
for (class<?> clazz:target.getInterfaces ()) {
Resolvedatasource ( Clazz, Signature.getmethod ());
}
Resolvedatasource (target, Signature.getmethod ());
}

/**
* Extraction of target object method annotations and data source identification in type annotations
*
* @param clazz
* @param method
*/
private void Resolvedatasource (Class<?> clazz, method) {
try {
class<?>[] types = Method.getparametertypes ();
Default usage type annotations
if (Clazz.isannotationpresent (Datasource.class)) {
DataSource Source = clazz.getannotation (Datasource.class);
Dynamicdatasourceholder.setdatasource (Source.value ());
}
Method annotations can override type annotations
Method m = Clazz.getmethod (Method.getname (), types);
if (m! = null && m.isannotationpresent (Datasource.class)) {
DataSource Source = m.getannotation (Datasource.class);
Dynamicdatasourceholder.setdatasource (Source.value ());
}
} catch (Exception e) {
System.out.println (Clazz + ":" + e.getmessage ());
}
}

}

Spring configures multiple data sources (case)

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.