Spring implements read-write separation AOP annotation method

Source: Internet
Author: User

1. The scene, to achieve the database read and write separation.

2. Thinking, since it is read and write separation, that is the need to switch between different data sources, one is static switching, is configured in advance two static database resources, there is a dynamic switch resources, here to spring, it is necessary to know how spring dynamically switch data sources.

3.spring provides a dynamic switch data source interface Abstractroutingdatasource, about Abstractroutingdatasource This class we can look at its source code

protectedDataSource Determinetargetdatasource () {Assert.notnull ( This. resolveddatasources, "DataSource Router not initialized"); Object LookupKey=Determinecurrentlookupkey (); DataSource DataSource= This. Resolveddatasources.get (LookupKey); if(DataSource = =NULL&& ( This. lenientfallback | | LookupKey = =NULL) ) {DataSource= This. Resolveddefaultdatasource; }        if(DataSource = =NULL) {            Throw NewIllegalStateException ("Cannot determine target DataSource for lookup key [" + LookupKey + "]"); }        returnDataSource; }

can see call Determinecurrentlookupkey () This method to get the key, and then according to the key to get the corresponding data source, this time we can integrate this rewrite this method code is as follows:

 Public class extends abstractroutingdatasource{    @Override    protected  Object Determinecurrentlookupkey () {         // TODO auto-generated Method stub        return Dynamicdatasourceholder.getdatasource ();    }}

Dynamicdatasourceholder class:

 Public class Dynamicdatasourceholder {        publicfinalstaticnew threadlocal< String>();          Public Static void Putdatasource (String name) {        holder.set (name);    }          Public Static String Getdatasource () {        return  holder.get ();    }}

The use of threadlocal is to prevent concurrency problems and to ensure that each thread is using its own data source.

The method that gets the key above will be used below.

3. Resolved the dynamic Fetch data source The following is how to switch to a read data source when I invoke the Read method, and then switch to the write data source when the write operation is implemented.

Here you can use Spring AOP for aspect programming, for ease of operation we can write a custom annotation using custom annotations to annotate that method is read operation that method is a write operation

@Retention (retentionpolicy.runtime) @Target (Elementtype.method)  public @Interface  DataSource {        String value ();}

AOP classes:

@Component @aspect Public classdaoaspect {@Pointcut ("Execution (* com.kedacom.aop.service.*.* (..))")     Public voidread () {} @Before ("Read ()")     Public voidBeforeread (Joinpoint point) {Object Object=Point.gettarget (); //Get method NameString MethodName =point.getsignature (). GetName (); Class<?>[] Parametertypes =((methodsignature) point.getsignature ()). GetMethod (). Getparametertypes (); Try {            //get to MethodMethod method =Object.getclass (). GetMethod (MethodName, parametertypes); //get the value in the noteDataSource DataSource = method.getannotation (DataSource.class); //get key for master and slave database to switch databaseString Dbkey =Datasource.value ();                        Dynamicdatasourceholder.putdatasource (Dbkey);                    System.out.println (Dbkey); } Catch(Exception e) {//Todo:handle ExceptionE.printstacktrace (); }        }}

This is used to annotate the AOP feature.

Two service classes:

 @Service ("Readservice"  public  Span style= "COLOR: #0000ff" >class   Readservice {@Resource (name  = "Userdao"         = "Slave"  public   User Readuser (String id) { return
       Userdao.getuser (ID); }}
@Service ("Writeservice")publicclass  writeservice {    @Resource (name= " Userdao ")    Userdao Userdao;        @DataSource (Value= "Master")    publicvoid  writedb (user user) {        Userdao.save (user);}    }

Test code:

 Public Static voidMain (string[] args) {ApplicationContext ctx=NewClasspathxmlapplicationcontext ("Applicationcontext.xml"); //Personserver bean = (personserver) ctx.getbean ("Personservicebean");//bean.save ("Fasdfa");Writeservice ws = (writeservice) ctx.getbean ("Writeservice"); User User=NewUser (); User.setid ("123"); User.setname ("XXX"); USER.SETPASSWD ("OK");                Ws.writedb (user); Readservice RS= (Readservice) ctx.getbean ("Readservice"); User u= Rs.readuser ("1"); System.out.println (U.getid ()+ "--" +u.getname () + "--" +u.getpasswd ()); }

Spring Configuration:

<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans"XMLNS:AOP= "HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOP" xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"Xmlns:context= "Http://www.springframework.org/schema/context" xmlns:tx= "Http://www.springframework.org/schema/tx"Xmlns:dwr= "Http://www.directwebremoting.org/schema/spring-dwr"Xmlns:dwra= "Http://www.directwebremoting.org/schema/spring-dwr-annotations"xsi:schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp//WWW.SPRINGFRAMEWORK.ORG/SCHEMA/AOPhttp//www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp//Www.springframework.org/schema/contexthttp//www.springframework.org/schema/context/spring-context-3.2.xsdhttp//Www.springframework.org/schema/txhttp//www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp//Www.directwebremoting.org/schema/spring-dwrhttp//www.directwebremoting.org/schema/spring-dwr-3.0.xsdhttp//www.directwebremoting.org/schema/spring-dwr-annotationshttp//www.directwebremoting.org/schema/spring-dwr-annotations.xsd "><context:annotation-config/> <context:component-scan base- Package= "com.guo.*,com.kedacom.*"/> <aop:aspectj-autoproxy/> <bean id= "Personservicebean"class= "Com.guo.test.PersonServerBean"/> <!--<bean id= "Myinterceptor"class= "Com.guo.test.MyInterceptor"/>--<!--main database Source--<bean id= "Masterdatasource"class= "Org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name= "url" value= "jdbc:mysql:// Localhost:3306/maven?useunicode=true&amp;characterencoding=utf-8 "/> <property name=" username "value=" Root "/> <property name=" password "value=" root "/> <property name=" driverclassname "value=" Com.mys Ql.jdbc.Driver "/> </bean> <!--from database Source-<bean id=" Slavedatasource "class= "Org.springframework.jdbc.datasource.DriverManagerDataSource" > <property name= "url" value= "jdbc:mysql:// Localhost:3306/test_user?useunicode=true&amp;characterencoding=utf-8 "/> <property name=" username "value = "root"/> <property name= "password" value= "root"/> <property name= "driverclassname" value= "COM.M Ysql.jdbc.Driver "/> </bean> <!--Configuring Dynamic Data Sources--<bean id=" DataSource "class= "Com.kedacom.aop.DynamicDataSource" > <property name= "targetdatasources" > <map key-type= "Java.lang.String" > <!--write--<entry key= "master" value-ref= "Masterdat                 Asource "/> <!--read--<entry key=" slave "value-ref=" Slavedatasource "/> </map> </property> <!--default data source-<property Nam E= "Defaulttargetdatasource" ref= "Masterdatasource"/> </bean> <bean id= "Daojdbctemplate"class= "Org.springframework.jdbc.core.JdbcTemplate" > <property name= "dataSource" ref= "DataSource"/> </bea N></beans>

Spring implements read-write separation AOP annotation method

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.