Tabla de contenido
1. Spring AOP basado en la configuración XML
2. Use anotaciones para configurar AOP
3. Función de corte de puntos de SuppectJ
4. Notas de notificación de aspecto J
5. Configuración cero para implementar Spring IOC y AOP
AOP (programación orientada al aspecto) es una tecnología que implementa el control unificado múltiple horizontal de las funciones del programa a través de métodos de precompilación y agentes dinámicos durante el tiempo de ejecución. AOP es un suplemento para OOP y una parte importante del marco de primavera. Las diversas partes de la lógica comercial se pueden aislar mediante el uso de AOP, reduciendo así el acoplamiento entre las diversas partes de la lógica comercial, mejorando la reutilización del programa y mejorando la eficiencia del desarrollo. AOP se puede dividir en tejido estático y tejido dinámico. El tejido dinámico no requiere cambiar el módulo de destino. Spring Framework implementa AOP, y el uso de la anotación para configurar AOP es más conveniente e intuitivo que usar la configuración XML.
1. Spring AOP basado en la configuración XML
Antes de explicar la anotación para implementar la función AOP, primero use el aprendizaje anterior para configurar la función Spring AOP usando XML, de modo que sea para comparar y comprender mejor.
1.1.
<Project xmlns = "http://maven.apache.org/pom/4.0.0" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xsi: schemalocation g/xsd/maven-4.0.0.xsd "> <modelVersion> 4.0.0 </modelversion> <MoupRid> com.zhangguo </groupid> <artifactid> spring052 </artifactid> <Versión> 0.0.1-Snapshot </Version> <Artaging> jar </packaging> <name> spring052 </name> <srl> http://maven.apache.org </url> <perties> <ject.build.sourceEnding> utf-8 </project.build.sourceenning> <vernersion /Propiedades> <pendencias> <pendency> <MoupRoD> Junit </proupid> <artifactId> Junit </artifactId> <cope> test </scope> <Versión> 4.10 </versión> </pendency> <epardency> <proupid> org.springframework </groupid> <artifactid> spring-context </artifactid> <versión> $ {spring.version} </versión> </dependency> <pendency> <grupoID> org.aspectj </grupo) Dependencia> <Spendency> <MoupROD> CGLIB </GroupId> <AtifactId> cglib </artifactid> <versión> 3.2.4 </versión> </pendency> </pendencs> </proyecto>1.2.
paquete com.zhangguo.spring052.aop01;/*** La clase de destino está proxyed*/public class Math {// Agregar intd (int n1, int n2) {int resultado = n1+n2; System.out.println (n1+"-"+n2+"="+resultado); resultado = n1*n2;1.3. Editar los consejos de la clase de notificación. El código Java que debe usarse en AOP es el siguiente:
paquete com.zhangguo.spring052.aop01; importar org.spectj.lang.joinpoint;/*** Clase de notificación, lógica transversal**/public de clase pública {public void antes (unión jp) { ---------------------------------------------------------------------------------------------------1.4.
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" pringframework.org/schema/p "xmlns: aop =" http://www.springframework.org/schema/aop "xsi: schemalocation =" http://www.springframework.org/schema/Beanss http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframe.org/ aop-4.3.xsd "> <!-proxy object-> <bean id =" math "> </bean> <!-notificación-> <bean id =" advices "> </bean> <!-AOP Configuration-> <aop: config proxy-target-class =" true "> <!-sección-> <aop: aspecto ref =" abogados "> <!-punto-> <aop: <aop:" true "> <!-sección-> <aop: aspectos ref =" avisos "> <!-punto-> <aop:" expresión = "ejecución (* com.zhangguo.spring052.aop01.math.* (..))" id = "puntocut1"/> <!-Conecte el método de notificación y punto-cut-> <aop: antes de "antes" frijoles>
1.5.
paquete com.zhangguo.spring052.aop01; import org.springframework.context.applicationContext; import org.springframework.context.support.classpathxmlaPplicationContext; public class test {publicsatatic void main (String [] args) xml "); Math Math = Ctx.getBean (" Math ", Math.Class); int n1 = 100, n2 = 5; Math.Add (N1, N2);Resultados de ejecución:
2. Use anotaciones para configurar AOP
2.1. Es equivalente a agregar un Bean al archivo de configuración XML en el ejemplo anterior, <!-Proxy Object-> <Bean ID = "Math"> </reme>, y el código de la clase de matemáticas es el siguiente:
paquete com.zhangguo.spring052.aop02; importar org.springframework.stereotype.service;/*** La clase de destino es proxyed*/@Service ("Math") Public Class Math {// ADD Public int ADD (int n1, int n2) {int result = n1+n2; // sustituir public int sub (int n1, int n2) {int result = n1-n2; System.out.println (N1+"-"+n2+"="+resultado); println (n1+"/"+n2+"="+resultado);2.2.
paquete com.zhangguo.spring052.aop02; import org.aspectj.lang.joinpoint; import org.spectj.lang.annotation.aspect; import org.aspectj.lang.annotation.aspect; import org.spectj.lang.annotation.beber /@Componente@AspectPublic Class Advices {@bebore ("Ejecución (* com.zhangguo.Spring052.aop02.Math.*(..))") public void before(JoinPoint jp){ System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------El código anterior es básicamente el mismo que la siguiente configuración
<!-Notificaciones-> <bean id = "advices"> </bean> <!-Aop Configuration-> <aop: config proxy-target-class = "true"> <!-section-> <aop: aspecto ref = "advices"> <!-punto-> <aop: punto de punto = "ejecutivo (* com.zhangguo.spring052.aop01.math. <!-Conecte el método de notificación y el punto-> <aop: antes del método = "antes" PointCut-Ref = "PointCut1"/> <aop: después del método = "After" PointCut-Ref = "PointCut1"/> </aop: aspecto> </aop: config>
2.3.
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" pringframework.org/schema/p "xmlns: aop =" http://www.springframework.org/schema/aop "xmlns: context =" http://www.springframework.org/schema/context " xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beanss.xsd http://www.springframework.org/schema/conton /schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd "> <context: component-scan base-package = "com.zhangguo.spring052.aop02"> </context: component-scan> <aop: aspectoj-autoproxy proxy-target-class = "true"> </aop: ofugeJ-auToproxy> </domas>
2.4.
paquete com.zhangguo.spring052.aop02; import org.springframework.context.applicationContext; import org.springframework.context.support.classpathxmlaPplicationContex ml "); Math Math = Ctx.getBean (" Math ", Math.Class); int n1 = 100, n2 = 5; Math.Add (N1, N2);Resultados de ejecución:
3. Función de corte de puntos de SuppectJ
La función Tangent se puede colocar en una posición lógica transversal precisa. tener una orientación diferente.
@AspectJ usa la expresión de corte especial de SuppectJ para describir la sección.
Método Función de corte de punto: define los puntos de conexión describiendo la información del método de clase de destino.
Método Función de corte de punto de parámetro: define los puntos de conexión describiendo la información del parámetro del método de clase de destino.
Función de corte de punto de clase de destino: define los puntos de conexión describiendo la información de tipo de clase de destino.
Función de corte de punto de clase de agente: define los puntos de conexión describiendo la información de la clase proxy.
Funciones comunes de expresión de aspecto de aspecto:
La función de corte de punto más comúnmente utilizada es: ejecución (<modo modificador>? <Modo de tipo de retorno> <modo de nombre de método> (<modo de parámetro>) <modo de excepción>?) Función de corte de puntos, que puede satisfacer la mayoría de las necesidades.
Para mostrar las funciones de cada función tangente de punto, ahora se agrega una nueva clase Strutil, la clase es la siguiente:
paquete com.zhangguo.spring052.aop03; import org.springframework.stereotype.component; @Component ("Strutil") Public Class Strutil {public void show () {System.out.println ("Hello Strutil!");El código de prueba es el siguiente:
paquete com.zhangguo.spring052.aop03; import org.springframework.context.applicationContext; import org.springframework.context.support.classpathxmlapplicationContext; public class Test {Void void main (String [] args) ml "); imath math = ctx.getBean (" math ", math.class); int n1 = 100, n2 = 5; Math.Add (N1, N2);3.1.
paquete com.zhangguo.spring052.aop03; import org.aspectj.lang.joinpoint; import org.spectj.lang.annotation.aspect; import org.aspectj.lang.annotation.aspect; import org.spectj.lang.annotation.beber /@Componente@AspectPublic Class Advices {@bebore ("Ejecución (* com.zhangguo.spring052.aop03.math.*(..)) ") public void before (unkenpoint jp) {system.out.println (" ---------------------------------- "); System.out.println (jp.getSignature (). 3 paquetes se cortan en @After ("Ejecución (*com.zhangguo.spring052.aop03.*.*(..))") public void después (unión un punto jp) { System.out.println ("---------------------------------");Los resultados de la operación son los siguientes:
ejecución (<modo modificador>? <modo de tipo de retorno> <modo de nombre de método> (<modo de parámetro>) <modo de excepción>?)
3.2.
// dentro de la función de corte // com.zhangguo.spring052.aop03 Paquete Todos los métodos de todas las clases se cortan en @After ("dentro (com.zhangguo.spring052.aop03.*)") public void después (unión JP) {System.out.println ("-------------------------------------") ");3.3.
// esta función de corte de punto // implementa cualquier punto de conexión del objeto proxy de la interfaz imath @after ("this (com.zhangguo.spring052.aop03.imath)") public void después (unión jp) { -------------------------------------------------------------------------------------------3.4.
// Función de punto de punto args // requiere que el método tenga dos referencias de tipo int antes de que se tejiera en la lógica transversal @After ("args (int, int)") public void después (unión jp) {system.out.println ("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------- Si el tipo de parámetro no es el tipo de datos base, se requiere el nombre del paquete.
3.5.
Primero personalice una anotación que se pueda anotar en el método
paquete com.zhangguo.spring052.aop03; import java.lang.annotation.documented; import java.lang.annotation.elementType; import java.lang.annotation.retent ention(etentionPolicy.runtime)@documentedpublic @interface myanno {} //@anotation Point-Cut Función // requiere que el método debe anotarse com.zhangguo.spring052.aop03.myanno se tejerá en la lógica de corte transversal @after ("@annotation (com.zhangguo.spring052.aop03.myanno)") Public void (Joinpoint JP) {System.out.Println ("("; ";"-". } paquete com.zhangguo.spring052.aop03; import org.springframework.stereotype.component; @Component ("Strutil") public class Strutil {@myanno public void show () {System.out.println ("Hello Strutil!");Resultados de ejecución:
Otras funciones de corte de puntos con @ son para anotación
4. Notas de notificación de aspecto J
Las anotaciones de notificación de SuppeJ tienen 6, 5 se usan comúnmente y se utilizan menos introducciones.
Primero resuelva el problema de definir la multiplexación de tangente de punto, como se muestra en el siguiente código, el contenido de la función tangente de punto es exactamente el mismo:
paquete com.zhangguo.spring052.aop04; import org.aspectj.lang.joinpoint; import org.spectj.lang.annotation.aspect; import og.aspectj.lang.annotation.aspect; import org.spectj.lang.annotation.beber /@Componente@AspectPublic Class Advices {@bebore ("Ejecución (* com.zhangguo.Spring052.aop04.Math.*(..))") public void before(JoinPoint jp){ System.out.println("--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Primero puede definir una tangente y luego multiplexar de la siguiente manera:
paquete com.zhangguo.spring052.aop04; import org.aspectj.lang.joinpoint; import org.spectj.lang.annotation.aspect; importar org.spectj.lang.annotation.before; import org.spectj.lang.annotation.pointcut; importar org.springframe. /@Componente@AspectPublic Class Advices { // 切点 @PointCut ("Ejecutivo (* com.zhangguo.spring052.aop04.math.* (..))") public void Pointcut () {} @before ("punto ()") public void antes (unión JP) {System.out.println ("----------- 前置通知 -----"); )); System.out.println ("---------------------------------");Modifique el archivo Advices.java y agregue varios tipos de notificación de la siguiente manera:
paquete com.zhangguo.spring052.aop04; import org.spectj.lang.joinpoint; import org.spectj.lang.proceedingjoinpoint; import org.aspectj.lang.annotation.after; import org.lang.annotation.Afterrupturning; importar org.spectj.lang.Annotation. anotación.around; import org.spectj.lang.annotation.around; import org.spectj.lang.annotation.spect; import org.spectj.lang.annotation.before; importar; org.aspectj.lang.annotation.pointcut; importar org.springframework.stereotype.component;/*** clase de notificación, lógica transversal*/@componente@aspecto de clase pública advices {// corta @pointcut ("ejecutor (* com.zhangguo.spring052.aop04.math.a* (..)") ")") otice @before ("PointCut ()") Public Void antes (JoinPoint JP) { System.out.println (jp.getSignature (). GetName ()); --------------------------------------------------------------------------------------------------- Showable {system.out.println (pjp.getSignature (). GetName ()); --------------------------------------------------------------------------- AfterReturning (unión JP, resultado del objeto) {System.out.println (jp.getSignature (). getName ()); ------------------------------------------------------------------------------- System.out.println (jp.getSignature (). GetName ());Resultados de ejecución:
5. Configuración cero para implementar Spring IOC y AOP
Para lograr la configuración cero, según el ejemplo original, agregamos una nueva clase similar a un usuario como se muestra a continuación:
paquete com.zhangguo.spring052.aop05; usuario de clase pública {public void show () {system.out.println ("un objeto de usuario");Esta clase no está anotada y el contenedor no se administrará automáticamente. Dado que no hay un archivo de configuración XML, use uno como información de configuración, y el archivo ApplicationCFG.Java es el siguiente:
paquete com.zhangguo.spring052.aop05; import org.springframework.context.annotation.bean; importar org.springframework.context.annotation.componentscan; importar org.springfringfring.context.annotation.configuration; import Figuration // Clase de configuración utilizada para representar la clase actual como un contenedor, similar a <beachs/>@componentscan (basepackages = "com.zhangguo.spring052.aop05") // El rango de escaneo es equivalente al nodo de la configuración XML <context: component-scan/>@enableaspectJaUtoProxy (proxyTargetClass = true) // Proxy, equivalente a <aop: s. Uración, equivalente a <bean id = getUser/> @Bean Public User getUser () {return new User ();Cada parte de esta clase básicamente tiene una relación uno a uno con la configuración XML. El código de prueba es el siguiente:
paquete com.zhangguo.spring052.aop05; import org.springframework.context.applicationContex s) {// Inicializar contenedores a través de clases ApplicationContext CTX = new AnnotationConfigApplicationContext (ApplicationCfg.Class); = ctx.getBean ("getUser", user.class); Advenices.java es lo mismo que el anterior, sin ningún cambio, el resultado de ejecución es el siguiente:
Lo anterior es todo el contenido de este artículo.