重构方面的异常?

时间:2017-01-18 13:52:04

标签: java spring aop aspectj

我们有一个在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;
}

我很好奇是否可以使用方面对其进行重构或简化?

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

感谢。

1 个答案:

答案 0 :(得分:1)

我使用普通的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是如何由cour应用程序代码或错误处理方面创建和填充的:

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]