Java 重构方面的异常?

Java 重构方面的异常?,java,spring,aop,aspectj,Java,Spring,Aop,Aspectj,我们有一个在SpringMVC中开发的大型代码库。下面的代码到处重复 public @ResponseBody BaseResponse<String> getSomething() { BaseResponse<String> response = new BaseResponse<String>(); try { //something } catch (Exception e) { BaseErr

我们有一个在SpringMVC中开发的大型代码库。下面的代码到处重复

 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可以在方面中调用,但是在响应中设置错误如何


谢谢

我用纯Java+原生AspectJ重新创建了您的情况,因为我不是Spring用户。但是方面本身及其切入点在SpringAOP中应该是相同的,只是方面也需要是@组件

几个虚拟类:

包de.scrum_master.app; 导入java.lang.annotation.ElementType; 导入java.lang.annotation.Retention; 导入java.lang.annotation.RetentionPolicy; 导入java.lang.annotation.Target; @RetentionRetentionPolicy.RUNTIME @TargetElementType.METHOD public@interface ResponseBody{} 包de.scrum_master.app; 公共类基类错误{ 私人例外e; 公共基错误{ 这个。e=e; } 公共字符串getMessage{ 返回e.getMessage; } } 包de.scrum_master.app; 公共类异常处理程序{ 公共静态BaseError errorResponseException e{ 返回新的BaseError; } } 包de.scrum_master.app; 公共类基类响应{ 私有字符串体; 私有字符串错误=OK; 公营机构{ 这个身体=身体; } public void setErrorBaseError be{ 错误=be.getMessage; } @凌驾 公共字符串toString{ 返回BaseResponse[body=+body+,error=+error+]; } } 驱动程序应用程序:

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

还有另一种方法不作为方面的目标作为否定测试用例

包de.scrum_master.app; 导入java.util.Random; 公共类应用程序{ 私有静态最终随机数=新随机数; 公共静态无效字符串[]args{ 应用程序=新应用程序; 对于int i=0;i<5;i++{ System.out.printlnapplication.doSomething; System.out.printlnapplication.getSomething; System.out.printlnapplication.getSomethingElse; } } 公共字符串doSomething{ 返回做某事; } public@ResponseBody BaseResponse getSomething{ BaseResponse=新的BaseResponse; if RANDOM.nextBoolean 抛出新的RuntimeException无法获取某些内容; 回应。挫败某事; 返回响应; } public@ResponseBody BaseResponse getSomethingElse{ BaseResponse=新的BaseResponse; if RANDOM.nextBoolean 抛出新的RuntimeException无法获得其他内容; 回应,挫折,获得其他东西; 返回响应; } } 错误处理方面:

包de.scrum_master.aspect; 导入org.aspectj.lang.ProceedingJoinPoint; 导入org.aspectj.lang.annotation.Around; 导入org.aspectj.lang.annotation.Aspect; 导入de.scrum_master.app.BaseError; 导入de.scrum_master.app.BaseResponse; 导入de.scrum_master.app.ExceptionHandler; @面貌 公共类错误处理程序{ @Aroundexecutionde.scrum\u master.app.BaseResponse*。。 公共对象句柄错误处理连接点此连接点抛出可丢弃{ //System.out.printlnthisJoinPoint; 试一试{ 返回此连接点。继续; }捕获异常e{ BaseError be=ExceptionHandler.errorResponsee; BaseResponse=新的BaseResponse; 回应:哦!; response.setErrorbe; 返回响应; } } } 控制台日志:

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

做某事 BaseResponse[正文=获取内容,错误=确定] BaseResponse[body=uh-oh!,error=无法获取其他内容] 做某事 BaseResponse[body=uh-oh!,error=cannotgetsomething] BaseResponse[正文=获取其他内容,错误=确定] 做某事 BaseResponse[正文=获取内容,错误=确定] BaseResponse[正文=获取其他内容,错误=确定] 做某事 BaseResponse[正文=获取内容,错误=确定] BaseResponse[正文=获取其他内容,错误=确定] 做某事 BaseResponse[正文=获取内容,错误=确定] BaseResponse[body=uh-oh!,error=无法获取其他内容]
如果您使用的是Java8,我会使用一个采用lambda的helper方法,它在代码和运行时的开销都很小,并且不需要像AspectJ这样的新依赖项。如果您使用的是Java7或更低版本,AspectJ可能是一个选项,使用around advice是您用例的典型教科书示例。我会考虑你的建议的非常感谢
你的努力。我很感激。我只有一个简单的问题,我们实际上有相同的设计。在这种情况下,BaseResponse对aspect有效吗?不,这是不合逻辑的。在类定义之外,不能使用只有内部已知的泛型类型变量。如果您想匹配所有基本响应,只需使用BaseResponse,或者,如果您愿意,使用BaseResponse。或者,如果您认为方面有任何价值,请将其设置为通用方面。但是您必须将它声明为抽象的,并创建它的具体子类,例如@Aspect公共类StringErrorHandler Extendes ErrorHandler{}