java - 重构方面的异常?

标签 java spring aop aspectj spring-aop

我们有一个用 Spring MVC 开发的大型代码库。下面的代码到处重复。

 public @ResponseBody BaseResponse<String> getSomething() {
    BaseResponse<String> response = new BaseResponse<String>();
    try {
        //something
    } catch (Exception e) {
        BaseError be = ExceptionHandler.errorResponse(e);
        response.setError(be);
    }
    return response;
}

我很好奇是否可以使用方面来重构或简化?

即:可以在方面内调用 ExceptionHandler,但如何在响应中设置错误?

谢谢。

最佳答案

我用普通 Java + native AspectJ 重新创建了您的情况,因为我不是 Spring 用户。但是在 Spring AOP 中,切面和它的切入点应该是相同的,只是切面也需要是 @Component .

几个虚拟类:

package de.scrum_master.app;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResponseBody {}
package de.scrum_master.app;

public class BaseError {
    private Exception e;

    public BaseError(Exception e) {
        this.e= e;
    }

    public String getMessage() {
        return e.getMessage();
    }
}
package de.scrum_master.app;

public class ExceptionHandler {
    public static BaseError errorResponse(Exception e) {
        return new BaseError(e);
    }
}
package de.scrum_master.app;

public class BaseResponse<T> {
    private String body;
    private String error = "OK";

    public void setBody(String body) {
        this.body = body;
    }

    public void setError(BaseError be) {
        error = be.getMessage();
    }

    @Override
    public String toString() {
        return "BaseResponse [body=" + body + ", error=" + error + "]";
    }
}

驱动程序应用程序:

有两个目标方法返回 BaseResponse<String> ,基本上与示例方法相同,随机抛出异常,但剥离了异常处理。我想这就是您想要实现的目标。

还有另一种方法不作为该方面的目标(作为负面测试用例)。

package de.scrum_master.app;

import java.util.Random;

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 < 5; i++) {
            System.out.println(application.doSomething());
            System.out.println(application.getSomething());
            System.out.println(application.getSomethingElse());
        }
    }

    public String doSomething() {
        return "Doing something";
    }

    public @ResponseBody BaseResponse<String> getSomething() {
        BaseResponse<String> response = new BaseResponse<String>();
        if (RANDOM.nextBoolean())
            throw new RuntimeException("cannot get something");
        response.setBody("getting something");
        return response;
    }

    public @ResponseBody BaseResponse<String> getSomethingElse() {
        BaseResponse<String> response = new BaseResponse<String>();
        if (RANDOM.nextBoolean())
            throw new RuntimeException("cannot get something else");
        response.setBody("getting something else");
        return response;
    }
}

错误处理方面:

package de.scrum_master.aspect;

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

import de.scrum_master.app.BaseError;
import de.scrum_master.app.BaseResponse;
import de.scrum_master.app.ExceptionHandler;

@Aspect
public class ErrorHandler {
    @Around("execution(de.scrum_master.app.BaseResponse<String> *(..))")
    public Object handleError(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        //System.out.println(thisJoinPoint);
        try {
            return thisJoinPoint.proceed();
        } catch (Exception e) {
            BaseError be = ExceptionHandler.errorResponse(e);
            BaseResponse<String> response = new BaseResponse<String>();
            response.setBody("uh-oh!");
            response.setError(be);
            return response;
        }
    }
}

控制台日志:

在这里您可以清楚地看到每个 BaseResponse 是如何进行的由我们的应用程序代码或错误处理方面创建和填充:

Doing something
BaseResponse [body=getting something, error=OK]
BaseResponse [body=uh-oh!, error=cannot get something else]
Doing something
BaseResponse [body=uh-oh!, error=cannot get something]
BaseResponse [body=getting something else, error=OK]
Doing something
BaseResponse [body=getting something, error=OK]
BaseResponse [body=getting something else, error=OK]
Doing something
BaseResponse [body=getting something, error=OK]
BaseResponse [body=getting something else, error=OK]
Doing something
BaseResponse [body=getting something, error=OK]
BaseResponse [body=uh-oh!, error=cannot get something else]

关于java - 重构方面的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41721239/

相关文章:

java - 我怎样才能轻松地在 Eclipse 中只看到新的警告?

java - 二维数组结构算法

java - Hibernate Spatial - 遇到无效的字节序标志值

java - 在 JAX-RS 资源中组合 @Context 和 @RolesAllowed?

spring - 如何使用 Spring REST Docs 创建一个 curl 片段以使用双引号而不是单引号?

java - 使用 ArrayList 创建 HashMap

Java 堆转储 : How to find the objects/class that is taking memory by 1. io.netty.buffer.ByteBufUtil 2. byte[] 数组

java - Spring @Around > 参数的行为

c# - 为所有注册类型注册相同的 Unity 拦截和调用处理程序

c# - 使用 Microsoft Enterprise Library Unity 拦截方法时未返回完整堆栈跟踪