Einführung in das Spring Framework

Das Spring Framework basiert auf zwei Kernkonzepten – Dependency Injection und Aspektorientierte Programmierung (Spring AOP).

Spring AOP

Heute werden wir uns die Kernkonzepte der Aspektorientierten Programmierung anschauen und wie wir sie mit dem Spring Framework umsetzen können.

Überblick über Spring AOP

Die meisten Unternehmensanwendungen haben einige gemeinsame querschnittliche Anliegen, die für verschiedene Arten von Objekten und Modulen gelten. Einige der häufigen querschnittlichen Anliegen sind Logging, Transaktionsmanagement, Datenvalidierung usw. In der objektorientierten Programmierung wird die Modularität der Anwendung durch Klassen erreicht, während in der aspektorientierten Programmierung die Modularität durch Aspekte erreicht wird, die so konfiguriert sind, dass sie verschiedene Klassen durchschneiden. Spring AOP nimmt die direkte Abhängigkeit von querschnittlichen Aufgaben von Klassen heraus, die wir durch das normale objektorientierte Programmiermodell nicht erreichen können. Zum Beispiel können wir eine separate Klasse für das Logging haben, aber wiederum müssen die funktionalen Klassen diese Methoden aufrufen, um das Logging in der gesamten Anwendung zu erreichen.

Kernkonzepte der Aspektorientierten Programmierung

Bevor wir in die Implementierung von Spring AOP einsteigen, sollten wir die Kernkonzepte von AOP verstehen.

Aspekt

Ein Aspekt ist eine Klasse, die unternehmensweite Anliegen umsetzt, die sich über mehrere Klassen erstrecken, wie z. B. Transaktionsmanagement. Aspekte können eine normale Klasse sein, die durch Spring XML-Konfiguration konfiguriert wird, oder wir können Spring AspectJ-Integration verwenden, um eine Klasse als Aspekt mit der Annotation @Aspect zu definieren.

Join Point

Ein Join Point ist ein spezifischer Punkt in der Anwendung, wie z.B. Methodenausführung, Ausnahmebehandlung, Änderung von Objektvariablenwerten usw. In Spring AOP ist ein Join Point immer die Ausführung einer Methode.

Ratschlag

Advices sind Maßnahmen, die für einen bestimmten Join Point ergriffen werden. In Programmierbegriffen sind sie Methoden, die ausgeführt werden, wenn ein bestimmter Join Point mit passendem Pointcut in der Anwendung erreicht wird. Man kann sich Advices als Struts2-Interceptor oder Servlet-Filter vorstellen.

Pointcut

Pointcut sind Ausdrücke, die mit Join Points abgeglichen werden, um zu bestimmen, ob ein Advice ausgeführt werden muss oder nicht. Pointcut verwendet verschiedene Arten von Ausdrücken, die mit den Join Points abgeglichen werden, und das Spring Framework verwendet die AspectJ-Pointcut-Ausdruckssprache.

Zielobjekt

Das sind die Objekte, auf die Advices angewendet werden. Spring AOP wird mit Laufzeitproxies implementiert, sodass dieses Objekt immer ein proxied Objekt ist. Das bedeutet, dass zur Laufzeit eine Unterklasse erstellt wird, in der die Zielmethode überschrieben wird und Advices basierend auf ihrer Konfiguration einbezogen werden.

AOP Proxy

Die Implementierung von Spring AOP verwendet JDK Dynamic Proxy, um die Proxy-Klassen mit Zielklassen und Advice-Aufrufen zu erstellen, diese werden als AOP-Proxy-Klassen bezeichnet. Wir können auch CGLIB-Proxy verwenden, indem wir es als Abhängigkeit im Spring AOP-Projekt hinzufügen.

Verweben

Es ist der Prozess des Verknüpfens von Aspekten mit anderen Objekten, um die beratenen Proxy-Objekte zu erstellen. Dies kann zur Kompilierzeit, zur Ladezeit oder zur Laufzeit erfolgen. Spring AOP führt das Verweben zur Laufzeit durch.

Arten von AOP-Advice

Basierend auf der Ausführungsstrategie von Advice gibt es folgende Typen.

Before Advice

Diese Advices laufen vor der Ausführung der Join-Point-Methoden. Wir können die Annotation @Before verwenden, um einen Advice-Typ als Before Advice zu kennzeichnen.

After (finally) Advice

Ein Advice, der ausgeführt wird, nachdem die Join-Point-Methode fertig ausgeführt wurde, ob normal oder durch das Werfen einer Ausnahme. Wir können After Advice mit der Annotation @After erstellen.

After Returning Advice

Manchmal möchten wir, dass Advice-Methoden nur ausgeführt werden, wenn die Join-Point-Methode normal ausgeführt wird. Wir können die Annotation @AfterReturning verwenden, um eine Methode als After-Returning-Advice zu kennzeichnen.

After Throwing Advice

Dieses Advice wird nur ausgeführt, wenn die Join-Point-Methode eine Ausnahme wirft, wir können es verwenden, um die Transaktion deklarativ zurückzurollen. Wir verwenden die Annotation @AfterThrowing für diesen Typ von Advice.

Around Advice

Dies ist das wichtigste und mächtigste Advice. Dieses Advice umgibt die Join-Point-Methode, und wir können auch wählen, ob wir die Join-Point-Methode ausführen möchten oder nicht. Wir können Advice-Code schreiben, der vor und nach der Ausführung der Join-Point-Methode ausgeführt wird. Es ist die Verantwortung des Around-Advice, die Join-Point-Methode aufzurufen und Werte zurückzugeben, wenn die Methode etwas zurückgibt. Wir verwenden die Annotation @Around, um Around-Advice-Methoden zu erstellen.

Die oben genannten Punkte mögen verwirrend klingen, aber wenn wir uns die Implementierung von Spring AOP ansehen, wird alles klarer. Lassen Sie uns ein einfaches Spring-Projekt mit AOP-Implementierungen erstellen. Spring bietet Unterstützung für die Verwendung von AspectJ-Annotationen zur Erstellung von Aspekten, und wir werden diese aus Gründen der Einfachheit verwenden. Alle oben genannten AOP-Annotationen sind im Paket org.aspectj.lang.annotation definiert. Spring Tool Suite bietet nützliche Informationen über die Aspekte, daher würde ich Ihnen empfehlen, es zu verwenden. Wenn Sie nicht mit STS vertraut sind, empfehle ich Ihnen, sich das Spring MVC-Tutorial anzusehen, in dem ich erkläre, wie man es verwendet.

Spring AOP-Beispiel

Erstellen Sie ein neues einfaches Spring Maven-Projekt, sodass alle Spring-Core-Bibliotheken in den pom.xml-Dateien enthalten sind und wir sie nicht explizit einbeziehen müssen. Unser endgültiges Projekt wird wie das untenstehende Bild aussehen, wir werden uns die Spring-Core-Komponenten und Aspektimplementierungen im Detail ansehen.

Spring AOP AspectJ-Abhängigkeiten

Das Spring Framework bietet standardmäßig AOP-Unterstützung, aber da wir AspectJ-Annotationen zur Konfiguration von Aspekten und Advice verwenden, müssen wir sie in die pom.xml-Datei aufnehmen.

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework.samples</groupId>
    <artifactId>SpringAOPExample</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>

        <!-- Generic properties -->
        <java.version>1.6</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring -->
        <spring-framework.version>4.0.2.RELEASE</spring-framework.version>

        <!-- Logging -->
        <logback.version>1.0.13</logback.version>
        <slf4j.version>1.7.5</slf4j.version>

        <!-- Test -->
        <junit.version>4.11</junit.version>

        <!-- AspectJ -->
        <aspectj.version>1.7.4</aspectj.version>

    </properties>

    <dependencies>
        <!-- Spring and Transactions -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Logging with SLF4J & LogBack -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!-- AspectJ dependencies -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
    </dependencies>
</project>

Beachten Sie, dass ich aspectjrt und aspectjtools-Abhängigkeiten (Version 1.7.4) in das Projekt aufgenommen habe. Außerdem habe ich die Spring Framework-Version auf die neueste Version aktualisiert, die zum Zeitpunkt des Schreibens 4.0.2.RELEASE ist.

Modelklasse

Lassen Sie uns eine einfache Java-Bean erstellen, die wir für unser Beispiel verwenden werden, mit einigen zusätzlichen Methoden. Employee.java-Code:

package com.journaldev.spring.model;

import com.journaldev.spring.aspect.Loggable;

public class Employee {

    private String name;
    
    public String getName() {
        return name;
    }

    @Loggable
    public void setName(String nm) {
        this.name=nm;
    }
    
    public void throwException(){
        throw new RuntimeException("Dummy Exception");
    }   
}

Haben Sie bemerkt, dass die setName()-Methode mit der Loggable-Annotation annotiert ist? Es ist eine benutzerdefinierte Java-Annotation, die wir im Projekt definiert haben. Wir werden später auf deren Verwendung eingehen.

Serviceklasse

Lassen Sie uns eine Serviceklasse erstellen, um mit der Employee-Bean zu arbeiten. EmployeeService.java-Code:

package com.journaldev.spring.service;

import com.journaldev.spring.model.Employee;

public class EmployeeService {

    private Employee employee;
    
    public Employee getEmployee(){
        return this.employee;
    }
    
    public void setEmployee(Employee e){
        this.employee=e;
    }
}

Ich hätte Spring-Annotationen verwenden können, um sie als Spring-Komponente zu konfigurieren, aber wir werden in diesem Projekt eine XML-basierte Konfiguration verwenden. Die EmployeeService-Klasse ist sehr standardmäßig und bietet uns lediglich einen Zugangspunkt für Employee-Beans.

Spring Bean-Konfiguration mit AOP

Wenn Sie STS verwenden, haben Sie die Option, eine „Spring Bean Configuration File“ zu erstellen und das AOP-Schema-Namespace auszuwählen, aber wenn Sie eine andere IDE verwenden, können Sie es einfach in die Spring Bean-Konfigurationsdatei einfügen. Meine Projekt-Bean-Konfigurationsdatei sieht wie folgt aus. spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
    xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="https://www.springframework.org/schema/aop"
    xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

<!-- Enable AspectJ style of Spring AOP -->
<aop:aspectj-autoproxy />

<!-- Configure Employee Bean and initialize it -->
<bean name="employee" class="com.journaldev.spring.model.Employee">
    <property name="name" value="Dummy Name"></property>
</bean>

<!-- Configure EmployeeService bean -->
<bean name="employeeService" class="com.journaldev.spring.service.EmployeeService">
    <property name="employee" ref="employee"></property>
</bean>

<!-- Configure Aspect Beans, without this Aspects advices wont execute -->
<bean name="employeeAspect" class="com.journaldev.spring.aspect.EmployeeAspect" />
<bean name="employeeAspectPointcut" class="com.journaldev.spring.aspect.EmployeeAspectPointcut" />
<bean name="employeeAspectJoinPoint" class="com.journaldev.spring.aspect.EmployeeAspectJoinPoint" />
<bean name="employeeAfterAspect" class="com.journaldev.spring.aspect.EmployeeAfterAspect" />
<bean name="employeeAroundAspect" class="com.journaldev.spring.aspect.EmployeeAroundAspect" />
<bean name="employeeAnnotationAspect" class="com.journaldev.spring.aspect.EmployeeAnnotationAspect" />

</beans>

Für die Verwendung von Spring AOP in Spring-Beans müssen wir Folgendes tun:

  • AOP-Namespace deklarieren, wie xmlns:aop=“https://www.springframework.org/schema/aop“
  • Das Element aop:aspectj-autoproxy hinzufügen, um die Unterstützung von Spring AspectJ mit Auto-Proxy zur Laufzeit zu aktivieren
  • Aspekt-Klassen als andere Spring-Beans konfigurieren

Sie können sehen, dass ich viele Aspekte in der Spring-Bean-Konfigurationsdatei definiert habe, es ist Zeit, sie sich nacheinander anzusehen.

Spring AOP Before Aspect Beispiel

EmployeeAspect.java-Code:

package com.journaldev.spring.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class EmployeeAspect {

    @Before("execution(public String getName())")
    public void getNameAdvice(){
        System.out.println("Executing Advice on getName()");
    }
    
    @Before("execution(* com.journaldev.spring.service.*.get*())")
    public void getAllAdvice(){
        System.out.println("Service method getter called");
    }
}

Wichtige Punkte in der obigen Aspektklasse sind:

  • Aspektklassen müssen mit der @Aspect-Annotation versehen sein.
  • Die @Before-Annotation wird verwendet, um ein Before-Advice zu erstellen.
  • Der String-Parameter, der in der @Before-Annotation übergeben wird, ist der Pointcut-Ausdruck.
  • Das getNameAdvice()-Advice wird für jede Spring-Bean-Methode mit der Signatur public String getName() ausgeführt.
  • Wir können Sternchen (*) als Platzhalter in Pointcut-Ausdrücken verwenden, das getAllAdvice()-Advice wird auf alle Klassen im Paket com.journaldev.spring.service angewendet, deren Name mit get beginnt und keine Argumente akzeptiert.

Spring AOP Pointcut-Methoden und Wiederverwendung

EmployeeAspectPointcut.java-Code:

package com.journaldev.spring.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class EmployeeAspectPointcut {

    @Before("getNamePointcut()")
    public void loggingAdvice(){
        System.out.println("Executing loggingAdvice on getName()");
    }
    
    @Before("getNamePointcut()")
    public void secondAdvice(){
        System.out.println("Executing secondAdvice on getName()");
    }
    
    @Pointcut("execution(public String getName())")
    public void getNamePointcut(){}
    
    @Before("allMethodsPointcut()")
    public void allServiceMethodsAdvice(){
        System.out.println("Before executing service method");
    }
    
    //Pointcut to execute on all the methods of classes in a package
    @Pointcut("within(com.journaldev.spring.service.*)")
    public void allMethodsPointcut(){}
    
}

Das obige Beispiel ist sehr klar, anstelle von Ausdrücken verwenden wir den Methodennamen im Argument der Advice-Annotation.

Spring AOP JoinPoint und Advice-Argumente

EmployeeAspectJoinPoint.java-Code:

package com.journaldev.spring.aspect;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class EmployeeAspectJoinPoint {
    
    @Before("execution(public void com.journaldev.spring.model..set*(*))")
    public void loggingAdvice(JoinPoint joinPoint){
        System.out.println("Before running loggingAdvice on method="+joinPoint.toString());
        
        System.out.println("Arguments Passed=" + Arrays.toString(joinPoint.getArgs()));

    }
    
    //Advice arguments, will be applied to bean methods with single String argument
    @Before("args(name)")
    public void logStringArguments(String name){
        System.out.println("String argument passed="+name);
    }
}

Wir können JoinPoint als Parameter in den Advice-Methoden verwenden und damit die Methodensignatur oder das Zielobjekt erhalten. Wir können args()-Ausdrücke im Pointcut verwenden, um auf jede Methode angewendet zu werden, die dem Argumentmuster entspricht.

Spring AOP After Advice Beispiel

EmployeeAfterAspect.java-Code:

package com.journaldev.spring.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class EmployeeAfterAspect {

    @After("args(name)")
    public void logStringArguments(String name){
        System.out.println("Running After Advice. String argument passed="+name);
    }
    
    @AfterThrowing("within(com.journaldev.spring.model.Employee)")
    public void logExceptions(JoinPoint joinPoint){
        System.out.println("Exception thrown in Employee Method="+joinPoint.toString());
    }
    
    @AfterReturning(pointcut="execution(* getName())", returning="returnString")
    public void getNameReturningAdvice(String returnString){
        System.out.println("getNameReturningAdvice executed. Returned String="+returnString);
    }
    
}

Wir können within im Pointcut-Ausdruck verwenden, um das Advice auf alle Methoden in der Klasse anzuwenden. Wir können @AfterReturning-Advice verwenden, um das Objekt zu erhalten, das von der beratenen Methode zurückgegeben wird. Wir haben die Methode throwException() in der Employee-Bean, um die Verwendung von After Throwing-Advice zu zeigen.

Spring AOP Around Aspect Beispiel

EmployeeAroundAspect.java-Code:

package com.journaldev.spring.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class EmployeeAroundAspect {

    @Around("execution(* com.journaldev.spring.model.Employee.getName())")
    public Object employeeAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("Before invoking getName() method");
        Object value = null;
        try {
            value = proceedingJoinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("After invoking getName() method. Return value="+value);
        return value;
    }
}

Around-Advice erfordert immer ein ProceedingJoinPoint als Argument, und wir sollten dessen proceed()-Methode verwenden, um die beratene Methode des Zielobjekts aufzurufen. Wenn die beratene Methode etwas zurückgibt, ist es die Verantwortung des Advice, es an das aufrufende Programm zurückzugeben. Für void-Methoden kann das Advice null zurückgeben. Da Around-Advice die beratene Methode umschließt, können wir die Eingabe und Ausgabe der Methode sowie ihr Ausführungsverhalten kontrollieren.

Spring Advice mit benutzerdefiniertem Annotation-Pointcut

Wenn Sie sich alle oben genannten Advice-Pointcut-Ausdrücke ansehen, gibt es Chancen, dass sie auf einige andere Beans angewendet werden, wo es nicht beabsichtigt ist. Zum Beispiel könnte jemand eine neue Spring-Bean mit einer getName()-Methode definieren, und das Advice würde anfangen, darauf angewendet zu werden, obwohl es nicht beabsichtigt war. Deshalb sollten wir den Umfang des Pointcut-Ausdrucks so eng wie möglich halten. Ein alternativer Ansatz ist die Erstellung einer benutzerdefinierten Annotation und die Annotation der Methoden, auf die das Advice angewendet werden soll. Dies ist der Zweck der Employee setName()-Methode, die mit der @Loggable-Annotation annotiert ist. Die @Transactional-Annotation des Spring Frameworks ist ein großartiges Beispiel für diesen Ansatz für das Spring Transaction Management. Loggable.java-Code:

package com.journaldev.spring.aspect;

public @interface Loggable {

}

EmployeeAnnotationAspect.java-Code:

package com.journaldev.spring.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class EmployeeAnnotationAspect {

    @Before("@annotation(com.journaldev.spring.aspect.Loggable)")
    public void myAdvice(){
        System.out.println("Executing myAdvice!!");
    }
}

Die myAdvice()-Methode wird nur die setName()-Methode beraten. Dies ist ein sehr sicherer Ansatz, und wann immer wir das Advice auf irgendeine Methode anwenden wollen, müssen wir sie nur mit der Loggable-Annotation annotieren.

Spring AOP XML-Konfiguration

Ich bevorzuge immer Annotationen, aber wir haben auch die Möglichkeit, Aspekte in der Spring-Konfigurationsdatei zu konfigurieren. Zum Beispiel haben wir eine Klasse wie unten. EmployeeXMLConfigAspect.java-Code:

package com.journaldev.spring.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

public class EmployeeXMLConfigAspect {

    public Object employeeAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("EmployeeXMLConfigAspect:: Before invoking getName() method");
        Object value = null;
        try {
            value = proceedingJoinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("EmployeeXMLConfigAspect:: After invoking getName() method. Return value="+value);
        return value;
    }
}

Wir können es konfigurieren, indem wir die folgende Konfiguration in die Spring Bean-Konfigurationsdatei einfügen.

<bean name="employeeXMLConfigAspect" class="com.journaldev.spring.aspect.EmployeeXMLConfigAspect" />

<!-- Spring AOP XML-Konfiguration -->
<aop:config>
    <aop:aspect ref="employeeXMLConfigAspect" id="employeeXMLConfigAspectID" order="1">
        <aop:pointcut expression="execution(* com.journaldev.spring.model.Employee.getName())" id="getNamePointcut"/>
        <aop:around method="employeeAroundAdvice" pointcut-ref="getNamePointcut" arg-names="proceedingJoinPoint"/>
    </aop:aspect>
</aop:config>

Die AOP-XML-Konfigurationselemente sind klar aus ihrem Namen heraus, also werde ich nicht weiter darauf eingehen.

Spring AOP-Beispiel

Lassen Sie uns ein einfaches Spring-Programm haben und sehen, wie all diese Aspekte die Bean-Methoden durchschneiden. SpringMain.java-Code:

package com.journaldev.spring.main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.journaldev.spring.service.EmployeeService;

public class SpringMain {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
        EmployeeService employeeService = ctx.getBean("employeeService", EmployeeService.class);
        
        System.out.println(employeeService.getEmployee().getName());
        
        employeeService.getEmployee().setName("Pankaj");
        
        employeeService.getEmployee().throwException();
        
        ctx.close();
    }
}

Jetzt, wenn wir das obige Programm ausführen, erhalten wir die folgende Ausgabe.

Mar 20, 2014 8:50:09 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4b9af9a9: startup date [Thu Mar 20 20:50:09 PDT 2014]; root of context hierarchy
Mar 20, 2014 8:50:09 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Service method getter called
Before executing service method
EmployeeXMLConfigAspect:: Before invoking getName() method
Executing Advice on getName()
Executing loggingAdvice on getName()
Executing secondAdvice on getName()
Before invoking getName() method
After invoking getName() method. Return value=Dummy Name
getNameReturningAdvice executed. Returned String=Dummy Name
EmployeeXMLConfigAspect:: After invoking getName() method. Return value=Dummy Name
Dummy Name
Service method getter called
Before executing service method
String argument passed=Pankaj
Before running loggingAdvice on method=execution(void com.journaldev.spring.model.Employee.setName(String))
Arguments Passed=[Pankaj]
Executing myAdvice!!
Running After Advice. String argument passed=Pankaj
Service method getter called
Before executing service method
Exception thrown in Employee Method=execution(void com.journaldev.spring.model.Employee.throwException())
Exception in thread "main" java.lang.RuntimeException: Dummy Exception
	at com.journaldev.spring.model.Employee.throwException(Employee.java:19)
	at com.journaldev.spring.model.Employee$$FastClassBySpringCGLIB$$da2dc051.invoke()
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:644)
	at com.journaldev.spring.model.Employee$$EnhancerBySpringCGLIB$$3f881964.throwException()
	at com.journaldev.spring.main.SpringMain.main(SpringMain.java:17)

Man kann sehen, dass die Advices nacheinander basierend auf ihren Pointcut-Konfigurationen ausgeführt werden. Sie sollten sie nacheinander konfigurieren, um Verwirrung zu vermeiden. Das ist alles für das Spring AOP-Beispiel-Tutorial, ich hoffe, Sie haben effektive Grundlagen von AOP mit Spring gelernt und können mehr aus den Beispielen lernen. – Einführung 

Kostenlosen Account erstellen

Registrieren Sie sich jetzt und erhalten Sie Zugang zu unseren Cloud Produkten.

Das könnte Sie auch interessieren: