Spring configures multiple data sources (MySQL read-write separation)

Source: Internet
Author: User
Tags aop

Some time ago just changed a new company, and then see the project code with the database read and write separation of the architecture, and then curiosity stripped the code to see the next, overall is the use of spring AOP facets to achieve . See clearly in their own personal small project in the use of the next, test OK, so the following summary of the following process:

1, first define a data source annotation, it has two values, a corresponding write library (main library), a corresponding read library (from the library)

 Package Com.jdd.ds; import java.lang.annotation.*; @Target ({elementtype.method, elementtype.type}) @Retention ( Retentionpolicy.runtime) @Documented public @Interface  DataSource {    = " Datasourceread ";     = "Datasourcewrite";     default "Datasourcewrite";}

2. Add this annotation to the method that requires interception

 PackageCom.jdd.service.impl;ImportCom.jdd.dao.UserDao;ImportCom.jdd.ds.DataSource;ImportCom.jdd.pojo.User;ImportCom.jdd.service.UserService;Importorg.springframework.beans.factory.annotation.Autowired;ImportOrg.springframework.stereotype.Service; @Service ("UserService") Public classUserserviceimplImplementsuserservice{@AutowiredPrivateUserdao Userdao; @DataSource (Name=datasource.data_source_read) @Override PublicUser Getuserbynameandpassword (string name, string password) {returnUserdao.getuserbynameandpassword (name, password); } @DataSource (Name=datasource.data_source_write) @Override Public intinsertuser (user user) {returnuserdao.insertuser (user); }}

3. Then add an AOP facet configuration to the configuration file:

<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans"Xmlns:context= "Http://www.springframework.org/schema/context" xmlns:p= "http://www.springframework.org/schema/p"XMLNS:AOP= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xmlns:tx= "Http://www.springframework.org/schema/tx"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"xsi:schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http//Www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsdhttp//WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOPhttp://www.springframework.org/schema/aop/spring-aop-4.0.xsd Http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp//Www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><!--scan Package Load Service implementation class-<context:component-scan base- Package= "Com.jdd.service" ></context:component-scan> <bean id= "Datasourceexchange"class= "Com.jdd.ds.DataSourceExchange" ></bean> <aop:config> <aop:aspect ref= "Datasourceexchange" > <aop:around method= "Execute" pointcut= "Within (com.jdd.service.impl.*)" ></aop:around> </a Op:aspect> </aop:config> </beans>

4. Then we'll get the value set in the DataSource annotation on the method in the slice class to decide which data source to use

 PackageCom.jdd.ds;ImportOrg.aspectj.lang.ProceedingJoinPoint;Importorg.aspectj.lang.Signature;Importorg.aspectj.lang.reflect.MethodSignature;ImportOrg.slf4j.Logger;Importorg.slf4j.LoggerFactory;ImportJava.lang.reflect.Method; Public classDatasourceexchange {Private StaticLogger Logger = Loggerfactory.getlogger (datasourceexchange.class);  PublicObject Execute (proceedingjoinpoint pjp) {logger.info ("Datasourceexchange==>"); Object obj=NULL; Signature Signature=pjp.getsignature (); Methodsignature methodsignature=(methodsignature) signature; Method Targetmethod=Methodsignature.getmethod (); Method Realmethod=NULL; Try{Realmethod=pjp.gettarget (). GetClass (). Getdeclaredmethod (Signature.getname (), targetmethod.getparametertypes ()); if(Realmethod.isannotationpresent (DataSource.class) {DataSource DataSource= (DataSource) realmethod.getannotation (DataSource.class);                Datasourcecontext.setdbtype (Datasource.name ()); Logger.info (Realmethod.getname ()+ "Set dbtype==>" +datasource.name ()); }Else{Datasourcecontext.setdbtype ("Datasourcewrite"); } obj=pjp.proceed (); } Catch(Throwable t) {t.printstacktrace (); } logger.info (Realmethod.getname ()+ "Clear datatype==>");        Datasourcecontext.cleardbtype (); returnobj; }}

Before the method executes, set a specific data source, and then clear the value after the method finishes executing.

  Note : Notice the code above that gets the business method through reflection, starting with

Methodsignature signature = (methodsignature) pjp.getsignature ();

Method method = Signature.getmethod ();

Found in this method, it is not annotated information. Later on the Internet search, presumably that this method is obtained is the proxy method, not the target method . The proxy method is not annotated with information, so this block is noted.

5, the following look at the Datasourcecontext class, the role of nature is to set the data source context.

 PackageCom.jdd.ds; Public classDatasourcecontext { Public Static FinalString data_source_read = "Datasourceread";  Public Static FinalString data_source_write = "Datasourcewrite"; Private Static FinalThreadlocal<string> Contextholder =NewThreadlocal<string>();  PublicDatasourcecontext () {} Public Static voidSetdbtype (String dbType) {contextholder.set (dbType); }     Public StaticString Getdbtype () {return(String) contextholder.get (); }     Public Static voidCleardbtype () {contextholder.remove (); }}

6. Define the Multipledatasource class below, inherit the Abstractroutingdatasource class with spring, and rewrite its determinecurrentlookupkey method, which is to get the identity of the data source used by the current thread from the context:

 PackageCom.jdd.ds;ImportOrg.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; Public classMultipledatasourceextendsabstractroutingdatasource{@OverrideprotectedObject Determinecurrentlookupkey () {Object key=Datasourcecontext.getdbtype (); if(Key! =NULL){             This. Logger.info ("The data source used by the current thread is identified as [" + key.tostring () + "]."); }        returnkey; }}

7, finally in the configuration file Applicationcontext-mysql.xml with the data source

<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans"Xmlns:context= "Http://www.springframework.org/schema/context" xmlns:p= "http://www.springframework.org/schema/p"XMLNS:AOP= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xmlns:tx= "Http://www.springframework.org/schema/tx"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"xsi:schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http//Www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-4.0.xsdhttp//WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOPhttp://www.springframework.org/schema/aop/spring-aop-4.0.xsd Http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsdhttp//Www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-4.0.xsd"><!--load Profiles--<context:property-placeholder location= "classpath:resource/*.properties"/> <!--database connection Pool--<bean id= "Datasourcewrite"class= "Com.alibaba.druid.pool.DruidDataSource"Destroy-method= "Close" > <property name= "driverclassname" value= "Com.mysql.jdbc.Driver"/> <property nam  e= "url" value= "${url.write}"/> <property name= "username" value= "${username.write}"/> <property  Name= "Password" value= "${password.write}"/> <property name= "maxactive" value= "ten"/> <property Name= "Minidle" value= "5"/> </bean> <bean id= "Datasourceread"class= "Com.alibaba.druid.pool.DruidDataSource"Destroy-method= "Close" > <property name= "driverclassname" value= "Com.mysql.jdbc.Driver"/> <property nam e= "url" value= "${url.read}"/> <property name= "username" value= "${username.read}"/> <property n Ame= "Password" value= "${password.read}"/> <property name= "maxactive" value= "ten"/> <property na Me= "Minidle" value= "5"/> </bean> <bean id= "Multipledatasource"class= "Com.jdd.ds.MultipleDataSource" > <property name= "defaulttargetdatasource" ref= "Datasourcewrite"/> <property name= "Targetdatasources" > <map> <entry value-ref= "Datasourcewrite" key = "Datasourcewrite" ></entry> <entry value-ref= "Datasourceread" key= "Datasourceread" ></entr y> </map> </property> </bean> <!--sqlsessionfactory--<bean ID = "Sqlsessionfactory"class= "Org.mybatis.spring.SqlSessionFactoryBean" > <property name= "configlocation" value= "classpath:mybatis/ Sqlmapconfig.xml "></property> <property name=" DataSource "ref=" Multipledatasource "></property&        Gt <property name= "mapperlocations" value= "Classpath:com/jdd/mapper/*.xml" ></property> </bean>< /beans>

8, to here and spring-related configuration is basically finished, in fact, after the configuration of MySQL master and slave replication, is the operation of the write library is synchronized to the library, so that the library from the library data is consistent. Specific configuration operation I will not write, you can search on the internet on their own.

Spring configures multiple data sources (MySQL read-write separation)

Related Article

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.