Ich glaube, dass Ihre Erwartung falsch ist (dass nur ein Schnittverfahren wird Übereinstimmen ähnlich wie beim Überladen von Methoden).
Aber während RuntimeException
ist Elternteil DataAccessException
beide Methoden ausgeführt werden ...
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<context:component-scan base-package="test" />
<aop:aspectj-autoproxy />
</beans>
AopTest
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:spring.xml");
MyService ms = ac.getBean(MyService.class);
try {
ms.throw1();
} catch (Exception e) {
// e.printStackTrace();
}
try {
ms.throw2();
} catch (Exception e) {
// e.printStackTrace();
}
}
}
MyAspect
package test;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(DataAccessException ex) throws Exception {
//throw DatabaseException
System.out.println("DAE");
}
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(RuntimeException ex) throws Exception {
//throw ServiceException
System.out.println("RE - " + ex.getClass());
}
}
MyService
package test;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
@Service
public class MyService {
public void throw1() throws DataAccessException {
throw new MyDataAccessException("test");
}
public void throw2() {
throw new NullPointerException();
}
static class MyDataAccessException extends DataAccessException {
public MyDataAccessException(String msg) {
super(msg);
}
}
}
und in Protokoll gibt es:
DAE
RE - class test.MyService$MyDataAccessException
RE - class java.lang.NullPointerException
Maven Abhängigkeiten:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
From Spring documentation:
Wenn zwei Ratschläge im gleichen Aspekt definiert beide müssen an der gleichen Stelle kommen laufen, wird die Bestellung nicht definiert (da gibt es keine Möglichkeit, die Erklärung, um über Reflektion abzurufen für javac- kompilierte Klassen). Ziehen Sie in Erwägung, solche Beratungsmethoden in einer Beratungsmethode pro Verknüpfungspunkt in jeder Aspektklasse zusammenzufassen oder die Ratschläge in separate Aspektklassen umzuwandeln, die auf der Aspektebene geordnet werden können.
Wenn ich folgende Modifikation von MyAspect
versucht:
package test;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(DataAccessException ex) throws Exception {
//throw DatabaseException
System.out.println("DAE");
throw new IllegalArgumentException("DAE"); // added
}
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(RuntimeException ex) throws Exception {
//throw ServiceException
System.out.println("RE - " + ex.getClass());
throw new IllegalArgumentException("RE"); // added
}
}
Protokoll geändert:
DAE
RE - class java.lang.IllegalArgumentException
RE - class java.lang.NullPointerException
und wann Exception
geändert Ich habe:
package test;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MyAspect {
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(DataAccessException ex) throws Exception {
//throw DatabaseException
System.out.println("DAE");
throw new Exception("DAE2"); // changed
}
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(RuntimeException ex) throws Exception {
//throw ServiceException
System.out.println("RE - " + ex.getClass());
throw new Exception("RE2"); // changed
}
}
das Protokoll war
DAE
RE - class java.lang.NullPointerException
glaube ich, dass Lösung für Ihr "Problem" zwei Aspekte zu haben, statt ein und definieren Sie die Bestellung:
package test;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class DaeAspect implements Ordered {
public int getOrder() {
return 200;
}
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(DataAccessException ex) throws Exception {
//throw DatabaseException
System.out.println("DAE");
throw new IllegalAccessException("DAE2"); // based on my testing, this stops second aspect to apply
}
}
und
package test;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ReAspect implements Ordered {
public int getOrder() {
return 100;
}
@AfterThrowing(pointcut = "execution(public * *(..))", throwing = "ex")
public void intercept(RuntimeException ex) throws Exception {
//throw ServiceException
System.out.println("RE - " + ex.getClass());
throw new IllegalAccessException("RE2");
}
}
Mit "falscher Methode" Sie meinten, dass beide Methoden ausgeführt werden, nicht wahr? – Betlista
Nein. Nur die Methode 'intercept (RuntimeException)'. – Francesco
Können Sie meine Antwort überprüfen und teilen, was in Ihrem Fall anders ist? Sie haben Spring Version, Definition von 'onlyServiceClasses' und andere Details nicht geteilt ... – Betlista