Das Frühlings-AOP-Framework ( Aspekt-orientierte Programmierung ) wird zur Modularisierung von Querschnittsthemen in Aspekten verwendet. Einfach gesagt, es ist nur ein Interceptor, um einige Prozesse abzufangen. Wenn zum Beispiel eine Methode ausgeführt wird, kann Spring AOP die ausgeführte Methode übernehmen und vor oder nach der Methodenausführung zusätzliche Funktionen hinzufügen.
In Spring AOP werden 4 Arten von Empfehlungen unterstützt:
-
Vor dem Rat - Vor der Ausführung der Methode ausführen
-
Nach Rückgabe des Hinweises - Nach Ausführen der Methode wird ein Ergebnis zurückgegeben
-
Nach dem Werfen von Ratschlägen - Run after the method löst eine Ausnahme aus
-
Rund um den Rat - Führen Sie die Methodenausführung aus und kombinieren Sie alle drei
Ratschläge oben.
Das folgende Beispiel zeigt Ihnen, wie Spring AOP-Ratschläge funktionieren.
Ein einfaches Springbeispiel
Erstellen Sie eine einfache Kundendienstklasse mit wenigen Druckmethoden zur späteren Demonstration.
package com.mkyong.customer.services; public class CustomerService { private String name; private String url; public void setName(String name) { this.name = name; } public void setUrl(String url) { this.url = url; } public void printName() { System.out.println("Customer name : " + this.name); } public void printURL() { System.out.println("Customer website : " + this.url); } public void printThrowException() { throw new IllegalArgumentException(); } }
Datei: Spring-Customer.xml - Eine Bean-Konfigurationsdatei
<beans xmlns="http://www.springframework.org/schema/beans" 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-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim"/> <property name="url" value="/"/> </bean> </beans>
Starte es
package com.mkyong.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mkyong.customer.services.CustomerService; public class App { public static void main(String[]args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[]{ "Spring-Customer.xml" }); CustomerService cust = (CustomerService) appContext.getBean("customerService"); System.out.println("** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** "); cust.printName(); System.out.println("** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** "); cust.printURL(); System.out.println("** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** "); try { cust.printThrowException(); } catch (Exception e) { } } }
Ausgabe
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Name des Kunden: Yong Mook Kim ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Kundenwebsite:/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
A simple Spring project to DI a bean and output some Strings.
Spring AOP Advices
Now, attach Spring AOP advices to above customer service.
1. Before advice
It will execute before the method execution. Create a class which implements MethodBeforeAdvice interface.
Paket com.mkyong.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; Die öffentliche Klasse HijackBeforeMethod implementiert MethodBeforeAdvice { @Überfahren public void before (Methodenmethode, Objekt[]Argumente, Objektziel) wirft Throwable { System.out.println ("HijackBeforeMethod: Before-Methode hijacked!"); } }
Erstellen Sie in der Bean-Konfigurationsdatei (Spring-Customer.xml) eine Bean für HijackBeforeMethod -Klasse und ein neues Proxy-Objekt mit dem Namen ' CustomerServiceProxy '.
-
"Target" - Definieren Sie, welche Bean Sie entführen möchten.
-
'InterceptorNames' - Legen Sie fest, für welche Klasse (Beratung) Sie sich bewerben möchten dieses Proxy-/Zielobjekt.
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www .springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "> <bean id = "customerService" class = "com.mkyong.customer.services.CustomerService"> <property name = "name" value = "Yong Mook Kim"/> <property name = "url" value = "/"/> </bean> <bean id = "hijackBeforeMethodBean" class = "com.mkyong.aop.HijackBeforeMethod"/> <bean id = "customerServiceProxy" class = "org.springframework.aop.framework.ProxyFactoryBean"> <property name = "target" ref = "customerService"/> <property name = "interceptorNames"> <Liste> <value> hijackBeforeMethodBean </value> </list> </property> </bean> </Beans>
-
Hinweis** Um Spring-Proxy verwenden zu können, müssen Sie die CGLIB2-Bibliothek hinzufügen. Füge unten in Maven hinzu pom.xml-Datei.
<Abhängigkeit> <groupId> cglib </groupId> <artifactId> cglib </artifactId> <Version> 2.2.2 </Version> </Abhängigkeit>
Führen Sie es erneut aus, jetzt erhalten Sie stattdessen die neue customerServiceProxy - Bean der ursprünglichen Bean customerService .
Paket com.mkyong.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mkyong.customer.services.CustomerService; öffentliche Klasse App {public static void main (String[]args) {ApplicationContext appContext = new ClassPathXmlApplicationContext (neuer String[]{"Spring-Customer.xml"}); CustomerService cust = (CustomerService) appContext.getBean ("customerServiceProxy"); System.out.println ("** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** "); cust.printName (); System.out.println ("** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** "); cust.printURL (); System.out.println ("** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** "); try {cust.printThrowException (); } catch (Ausnahme e) { } } }
Ausgabe
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** HijackBeforeMethod : Before method hijacked! Customer name : Yong Mook Kim ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** HijackBeforeMethod: Vor der Methode hijacked! Kundenwebsite:/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** HijackBeforeMethod: Vor der Methode hijacked!
Es wird die Methode before () von HijackBeforeMethods ausgeführt, bevor die Methoden von customerService ausgeführt werden.
2. Nach Rückgabe des Hinweises
Es wird ausgeführt, nachdem der Methode ein Ergebnis zurückgegeben wurde. Erstellen Sie eine Klasse, die die Schnittstelle AfterReturningAdvice implementiert.
package com.mkyong.aop; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class HijackAfterMethod implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[]args, Object target) throws Throwable { System.out.println("HijackAfterMethod : After method hijacked!"); } }
Bean-Konfigurationsdatei
<beans xmlns="http://www.springframework.org/schema/beans" 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-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim"/> <property name="url" value="/"/> </bean> <bean id="hijackAfterMethodBean" class="com.mkyong.aop.HijackAfterMethod"/> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService"/> <property name="interceptorNames"> <list> <value>hijackAfterMethodBean</value> </list> </property> </bean> </beans>
Führen Sie es erneut aus, Ausgabe
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Kundenname: Yong Mook Kim HijackAfterMethod: Nach Methode hijacked! ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Customer website :/HijackAfterMethod : After method hijacked! ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
It will run the HijackAfterMethod’s afterReturning() method, after every customerService’s methods that are returned result.
3. After throwing advice
It will execute after the method throws an exception. Create a class which implements ThrowsAdvice interface, and create a afterThrowing method to hijack the IllegalArgumentException exception.
Paket com.mkyong.aop; import org.springframework.aop.ThrowsAdvice; Die öffentliche Klasse HijackThrowException implementiert ThrowsAdvice { public void afterThrowing (IllegalArgumentException e) wirft Throwable { System.out.println ("HijackThrowException: Ausnahmebedingung hijacked!"); } }
Bean-Konfigurationsdatei
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www .springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "> <bean id = "customerService" class = "com.mkyong.customer.services.CustomerService"> <property name = "name" value = "Yong Mook Kim"/> <property name = "url" value = "/"/> </bean> <bean id = "hijackThrowExceptionBean" class = "com.mkyong.aop.HijackThrowException"/> <bean id = "customerServiceProxy" class = "org.springframework.aop.framework.ProxyFactoryBean"> <property name = "target" ref = "customerService"/> <property name = "interceptorNames"> <Liste> <value> hijackThrowExceptionBean </value> </list> </property> </bean> </Beans>
Führen Sie es erneut aus, Ausgabe
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Customer name : Yong Mook Kim ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Kundenwebsite:/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** HijackThrowException: Auslöser für Ausnahmefehler
Es wird die afterThrowing () - Methode der HijackThrowException ausgeführt, wenn die Methoden von customerService eine Ausnahme auslösen.
4. Um Ratschläge
Es fasst alle drei oben genannten Hinweise zusammen und wird während der Ausführung der Methode ausgeführt. Erstellen Sie eine Klasse, die die MethodInterceptor -Schnittstelle implementiert. Sie müssen methodInvocation.proceed (); ** ”aufrufen, um mit der Ausführung der ursprünglichen Methode fortzufahren, andernfalls wird die ursprüngliche Methode nicht ausgeführt.
package com.mkyong.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class HijackAroundMethod implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Method name : " + methodInvocation.getMethod().getName()); System.out.println("Method arguments : " + Arrays.toString(methodInvocation.getArguments())); //same with MethodBeforeAdvice System.out.println("HijackAroundMethod : Before method hijacked!"); try { //proceed to original method call Object result = methodInvocation.proceed(); //same with AfterReturningAdvice System.out.println("HijackAroundMethod : Before after hijacked!"); return result; } catch (IllegalArgumentException e) { //same with ThrowsAdvice System.out.println("HijackAroundMethod : Throw exception hijacked!"); throw e; } } }
Bean-Konfigurationsdatei
<beans xmlns="http://www.springframework.org/schema/beans" 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-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim"/> <property name="url" value="/"/> </bean> <bean id="hijackAroundMethodBean" class="com.mkyong.aop.HijackAroundMethod"/> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService"/> <property name="interceptorNames"> <list> <value>hijackAroundMethodBean</value> </list> </property> </bean> </beans>
Führen Sie es erneut aus, Ausgabe
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Name der Methode: printName Argumente der Methode:[]HijackAroundMethod: Vor der Methode hijacked! Kundenname: Yong Mook Kim HijackAroundMethod: Vorher nach dem Hijacking! ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Method name : printURL Method arguments :[]HijackAroundMethod : Before method hijacked! Customer website :/HijackAroundMethod : Before after hijacked! ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Name der Methode: printThrowException Argumente der Methode:[]HijackAroundMethod: Before-Methode hijacked HijackAroundMethod: Auslöser für Ausnahmebereitschaft!
It will run the HijackAroundMethod’s invoke() method, after every customerService’s method execution.
Conclusion
Most of the Spring developers are just implements the ‘Around advice ‘, since it can apply all the advice type, but a better practice should choose the most suitable advice type to satisfy the requirements.
-
Pointcut**
In this example, all the methods in a customer service class are intercepted (advice) automatically. But for most cases, you may need to use Pointcut and Advisor to intercept a method via it’s method name.