Spring AOP, la configuración MySQL Master-Slave realiza la separación de lectura y escritura. A continuación, registre su propio proceso de configuración y problemas encontrados para facilitar la próxima operación. También espero ayudar a algunos amigos.
1. Use el mecanismo de intercepción de AOP de resorte para realizar la selección dinámica de fuentes de datos.
import java.lang.annotation.ElementType; import java.lang.annotation.target; import java.lang.annotation.retention; import java.lang.annotation.retentionPolicy; /** * Tiempo de ejecución * El compilador registrará los comentarios en el archivo de clase, y la VM conservará los comentarios en tiempo de ejecución, por lo que se puede leer reflexivamente. * @author yangguang * */ @retention (retentionPolicy.runtime) @Target (elementType.method) public @Interface DataSource {String value (); } 3. Use el abstruco de SpringDataSource para resolver el problema de múltiples fuentes de datos
importar org.springframework.jdbc.dataSource.lookup.AbstracTroutingDataSource; La clase pública elección deltaseurce extiende AbstrutingDataSource {@Override Object DetdinECRENTORLOPLOPKEY () {return HandledataSource.getDataSource (); }} 4. Use ThreadLocal para resolver problemas de seguridad de los subprocesos
clase pública HandledataSource {public static final ThreadLocal <String> Holder = new ThreadLocal <String> (); public static void putDataSource (cadena dataSource) {holder.set (dataSource); } public static string getDataSource () {return holder.get (); }}5. Defina una clase de faceta de fuente de datos, accedida a través de AOP y se configura en el archivo de configuración de Spring, por lo que no se utiliza la anotación de AOP.
import java.lang.reflect.method; importar org.spectj.lang.joinpoint; importar org.spectj.lang.annotation.spect; importar org.spectj.lang.annotation.before; importar org.spectj.lang.annotation.pointcut; importar org.spectj.lang.reflect.methodsignature; importar org.springframework.stereotype.component; //@aspecto //@componente public class dataSourCeAspect {//@PointCut ("Ejecution (*com.apc.cms.service.*.*(..))") public void Pointcut () {}; // @bebore (value = "punto ()") public void antes (punto de unión) {Object Target = Point.GetTarget (); System.out.println (Target.ToString ()); Method de cadena = Point.getSignature (). GetName (); System.out.println (método); Clase <?> [] Classz = target.getClass (). GetInterfaces (); Clase <?> [] ParametertyPes = ((Methodsignature) Point.getSignature ()) .getMethod (). GetParametertyPes (); intente {método m = classz [0] .getMethod (método, parametertypes); System.out.println (m.getName ()); if (m! = null && m.isannotationPresent (dataSource.class)) {dataSource data = m.getAnnotation (dataSource.class); HandledataSource.putDataSource (data.Value ()); }} catch (Exception e) {E.PrintStackTrace (); }}}6. Configurar ApplicationContext.xml
< name="username" value="root"/> <property name="password" value="root"/> <property name="partitionCount" value="4"/> <property name="releaseHelperThreads" value="3"/> <property name="acquireIncrement" value="2"/> <property name="maxConnectionsPerPartition" value="40"/> <property name = "minconnectionsperPartition" valor = "20"/> <propiedad name = "idlemaxageInseconds" value = "60"/> <propiedad name = "idleconnectionTestperiDinSeconds" value = "60"/> <Property Name = "PoolAVailabilityThreshold" Value = "5"/> </ beon> <! destruye-method = "Close"> <Property Name = "DriverClass" value = "com.mysql.jdbc.driver"/> <Property name = "jdbcurl" value = "jdbc: mysql: //172.22.14.7: 3306/cpp? Autoreconnect = true"/> <name de propiedad = "name de propiedad" name "/" root "/>>>"/"contraseña =" contraseña " value = "root"/> <propiedad name = "partitionCount" value = "4"/> <propiedad name = "rotionHelperThreads" value = "3"/> <propiedad name = "adquirincrement" value = "2"/> <Property name = "MaxConnectionsPerTition" Value = "40"/> <Property Name = "MinConnectionsPerPartition" Valu name = "idlemaxageInseconds" valor = "60"/> <propiedad name = "idleconnectionTestperiodinSeconds" value = "60"/> <propiedad name = "petrowavailabilitythreshold" valor = "5"/> </bean> <!-Manager de transacciones, administración de transacciones-> <bean id = "TransActionManager"> <name de propiedad = "dataSource" refe ref = "refe ref =" Ref. < type = "Annotation" Expression = "org.springframework.steretype.component" /> < /context: component-scan> <context: component-scan base-package = "com.apc.cms.auth" /> <!-Encarable Demarcation de transacción con Annotations-> <tx: anotación-conducida /> <!-Define the sqlsession DeMarcation id = "SQLSessionFactory"> <Property Name = "DataSource" ref = "DataSource" /> <Property Name = "TypeAliasSpackage" Value = "com.apc.cms.model.domain" /> < /bean> <!-escanear los mapeadores y dejar que sean automáticos-> <bean> <name de propiedad = "basepackage" value = "com.ap.apc.cms.perss.cms.perss. name = "SqlSessionFactory" ref = "SqlSessionFactory"/> </ bean> <bean id = "dataSource"> <propiedad name = "targetDataSources"> <map key-type = "java.lang.string"> <!-write-> <Entry key = "write" value-ref = "writedataSource"/> <!-<innition <inying key "wey" " value-ref = "readDataSource"/> </s map> </property> <Property name = "defaultTargetDataSource" ref = "writedataSource"/> </ bean> <!-activar la función de proxy automática-> <aop: spectJ-autopproxy id = "DataSourCeAspect"/> <aop: config> <aop: aspecto id = "c" ref = "dataSourCeAspect"> <aop: pointcut id = "tx" expresion = "ejecution (*com.apc.cms.service ..*.*(..))"/> <aop: antes de punto-ref = "tx" método = "antes"/> </> </aOP: <!-Configurar la anotación de la base de datos AOP->
7. Use anotaciones para seleccionar dinámicamente la fuente de datos, leer la biblioteca y escribir la biblioteca respectivamente.
@DataSource ("Write") public void Update (usuario de usuario) {usermapper.update (usuario); } @DataSource ("Read") Documento público GetDocByid (ID Long) {return documentMapper.getById (id); } Operación de escritura de prueba: puede modificar los datos a través de la aplicación y modificar los datos principales de la biblioteca. Encontrará que los datos en la biblioteca de esclavos se han actualizado sincrónicamente, por lo que las operaciones de escritura definidas están escritas en la biblioteca.
Operación de lectura de prueba: modifique los datos de la base de datos de esclavos en segundo plano, verifique que los datos en la base de datos principal no se hayan modificado, actualice en la página de la aplicación y encuentre que los datos en la base de datos de esclavos se leen, lo que significa que la separación de lectura y escritura está bien.
Resumen de los problemas encontrados:
Pregunta 1: El proyecto es un proyecto Maven, y se utiliza el mecanismo de Spring AOP. Además de los paquetes JAR de Spring, los paquetes JAR que deben usarse son SuppectJ.jar, SuppeJweaver.jar y Aopalliance.jar. Verifique el POM en el proyecto y descubra que falta el paquete de dependencia. Dado que el repositorio local no tiene estos frascos, busque la biblioteca Central Maven que pueda proporcionar la descarga del paquete JAR, configurarlo en Maven y actualizar automáticamente:
<Repository> <id> nexus </id> <name> nexus </name> <url> http://repository.sonatype.org/content/groups/public/ </ url> <lElout> default </dout> </ repository>
Los frascos que dependen para configurar el proyecto se pierden principalmente estos dos.
<Spendency> <ProupId> AspectJ </Groupid> <SartifactId> AspectJrt </artifactid> <versión> 1.5.4 </versión> </pendency> <pendency> <MoupRupid> AspectJ </GroupId> <AtifactId> AspectJWeaver </artifactId> <Version> 1.5.4 </lipsion> lt;/Dependency>
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.