gpt4 book ai didi

java - @AfterThrowing 没有按预期工作

转载 作者:搜寻专家 更新时间:2023-10-31 20:00:56 26 4
gpt4 key购买 nike

我想使用AOP来拦截所有在服务层抛出的运行时异常,并作为领域异常重新抛出。

@Aspect
@Component
public class ExceptionWrapperInterceptor {

@Pointcut("within(*.service.*)")
public void onlyServiceClasses() {}

@AfterThrowing(pointcut = "onlyServiceClasses()", throwing = "ex")
public void intercept(DataAccessException ex) throws Exception {
//throw DatabaseException
}

@AfterThrowing(pointcut = "onlyServiceClasses()", throwing = "ex")
public void intercept(RuntimeException ex) throws Exception {
//throw ServiceException
}

}

这里的问题是,对于 DataAccessException 的子类,运行时会执行错误的方法。有一个优雅的解决方案吗?

Spring 版本:4.2.4.RELEASE

附言具有大量 instanceof 的单个通用方法(从其他问题中读取)对我来说并不优雅;-)

谢谢弗朗切斯科

最佳答案

如何使用 @Around 建议?您可以在其中简单地使用类型安全的 try-catch,无需使用任何 instanceof 或反射。

这是我使用 AspectJ 而不是 Spring AOP 编译的一些示例代码,因为我不是 Spring 用户。无论如何,切入点应该是相同的。

辅助类:

package de.scrum_master.service;

public class DatabaseException extends RuntimeException {
public DatabaseException(Throwable arg0) {
super(arg0);
}
}
package de.scrum_master.service;

public class ServiceException extends RuntimeException {
public ServiceException(Throwable arg0) {
super(arg0);
}
}

驱动程序应用程序(纯 Java,无需使用 Spring):

package de.scrum_master.service;

import java.util.Random;
import org.springframework.jdbc.datasource.init.ScriptParseException;

public class Application {
private static final Random RANDOM = new Random();

public static void main(String[] args) {
Application application = new Application();
for (int i = 0; i < 10; i++) {
try {
application.doSomething();
}
catch (Exception e) {
System.out.println(e);
}
}
}

public void doSomething() {
switch (RANDOM.nextInt(3)) {
case 1: throw new ScriptParseException("uh-oh", null);
case 2: throw new IllegalArgumentException("WTF");
default: System.out.println("doing something");
}
}
}

看点:

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
import de.scrum_master.service.DatabaseException;
import de.scrum_master.service.ServiceException;

@Aspect
@Component
public class ExceptionWrapperInterceptor {
@Pointcut("within(*..service..*) && execution(* *(..))")
public void onlyServiceClasses() {}

@Around("onlyServiceClasses()")
public Object intercept(ProceedingJoinPoint thisJoinPoint) {
try {
return thisJoinPoint.proceed();
}
catch (DataAccessException dae) {
throw new DatabaseException(dae);
}
catch (RuntimeException re) {
throw new ServiceException(re);
}
}
}

控制台日志:

doing something
de.scrum_master.service.DatabaseException: org.springframework.jdbc.datasource.init.ScriptParseException: Failed to parse SQL script from resource [<unknown>]: uh-oh
doing something
de.scrum_master.service.DatabaseException: org.springframework.jdbc.datasource.init.ScriptParseException: Failed to parse SQL script from resource [<unknown>]: uh-oh
doing something
de.scrum_master.service.ServiceException: java.lang.IllegalArgumentException: WTF
de.scrum_master.service.ServiceException: java.lang.IllegalArgumentException: WTF
de.scrum_master.service.ServiceException: java.lang.IllegalArgumentException: WTF
de.scrum_master.service.ServiceException: java.lang.IllegalArgumentException: WTF
doing something

关于java - @AfterThrowing 没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34614073/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com