Spring AOP Beispiel - Hinweis

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.

Download Source Code

Download it – Spring-AOP-Advice-Examples.zip (8 KB)