使用注释进行异常处理? [英] Using annotations for exception handling?

查看:27
本文介绍了使用注释进行异常处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个抛出某种异常的方法.异常抛出代码位于访问外部服务的第三方库中.我有几个类可以与外部服务进行大量工作,并且有很多异常处理贯穿始终以处理潜在问题.我遇到的问题是我可能有很多异常,但如果有的话,我可能只需要执行几个操作之一,并且有大量的 try/catch 块.异常的类型甚至可能不相关,或者不同的方法可能抛出相同类型的异常,但需要根据抛出它的方法采取不同的动作.

Let's say I have a method that throws an Exception of some kind. The exception-throwing code lies in a third-party library that access an external service. I have a few classes that do a good deal of work with external services and there is a LOT of exception handling throughout to deal with potential problems. The issue I'm hitting is that I may have a lot of exceptions, but I may only need to perform one of a few actions if there is one, and there are a ton of try/catch blocks peppered about. The type of exception may not even be relevant, or different methods may throw the same type of exception, but different actions need to be taken depending on the method throwing it.

我正在寻找的是一个注释,它可以取代 try/catch 并简单地规定当该方法出现异常时要采取的行为.我知道 Spring ApsectJ 可以做这种事情,但我目前无法轻松添加任何新的依赖项或修改 pom 以调整现有的依赖项.因此,我希望这可以通过自定义注释来完成.例如:

What I'm looking for is an annotation that can supplant try/catch and simply dictate the behavior to be taken when there is an exception in that method. I know that Spring ApsectJ can do this sort of thing, but I'm not currently able to easily add any new dependencies or modify the pom to adjust existing ones. As such, I'm hoping that this can be accomplished with a custom annotation. For example:

@Catcher(action=SomeEnum.SOME_ACTION)
public void doSomething(ServiceObj obj) throws SomeException {
    ExternalService.makeThingsHappen(obj);
}

当然,我假设一个单独的类会处理异常.另一个困难是我还需要传递的 ServiceObj.如果 makeThingsHappen() 失败,我可能需要 obj 来执行其他操作.action 变量将告诉处理程序类如何处理 obj.

I would presume that a separate class would handle exceptions, of course. An additional difficulty is that I would need the ServiceObj that is passed as well. If makeThingsHappen() fails, I may need obj to perform additional actions. The action variable will tell the handler class what to do with obj.

这是否可以在没有严重破坏的情况下完成,还是我希望可能不存在的东西?

Can this be done without severe muckery, or am I hoping for something that may not exist?

推荐答案

这应该是一个低级的过程,并不是说我们不能和当前级别一样,只是可能需要一堆代码并且会使系统复杂一点.但是我的建议是这样的(我希望我是正确的),首先为想要处理异常的人定义一个接口,就像这样.

This should be a low-level process, and it doesn't mean we cannot have the same thing with current level, but it may needs a bunch of code and would complex the system a little. However my suggestion would be like this(I hope I got it correct), first define an interface for who wants to process exceptions, something like this.

interface ExceptionHandler{
  void handleException(Throwable t);
}

然后为用户(API)提供一个注解来标记它的方法可能会抛出一些异常.

then provide an annotation for user(API) to mark its methods may throws some exception.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
@interface Catch{
  public Class<? extends ExceptionHandler> targetCatchHandler();
  public Class<? extends Throwable> targetException() default Exception.class;
}


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface CatchGroup{
  public Catch[] catchers();
}

接下来我们需要一个接口来开始调用可能抛出异常的方法,就像这样.

next we need a interface to start to call the method which may throws exception, something like this.

interface Caller{
  void callMethod()throws Throwable;
}

那么你需要一个人来照顾和管理执行流程并调用可能的异常处理程序

then you need a guy who take care and manage the flow of the execution and call the possible exception handler

class MethodCaller{
  /*
   * @param isntance: instance which implemented the Caller interface
   */
  public static void callMethod(Caller instance)
      throws Exception {
    Method m = instance.getClass().getMethod("callMethod");
    Annotation as[] = m.getAnnotations();
    Catch[] li = null;
    for (Annotation a : as) {
      if (a.annotationType().equals(CatchGroup.class)) {
        li = ((CatchGroup) a).catchers();
      }
      // for(Catch cx:li){cx.targetException().getName();}
    }
    try {
      instance.callMethod();
    } catch (Throwable e) {
      Class<?> ec = e.getClass();
      if (li == null) {
        return;
      }
      for (Catch cx : li) {
        if (cx.targetException().equals(ec)) {
          ExceptionHandler h = cx.targetCatchHandler().newInstance();
          h.handleException(e);
          break;
        }
      }
    }
  }
}

最后,让我们举一些例子,它对我来说效果很好,很酷.异常处理程序.

and finally, lets have some example, it works very well for me, it's cool. the exception handler.

public class Bar implements ExceptionHandler{//the class who handles the exception
  @Override
  public void handleException(Throwable t) {
    System.out.println("Ta Ta");
    System.out.println(t.getMessage());
  }
}

和方法调用者.

class Foo implements Caller{//the class who calls the method
  @Override
  @CatchGroup(catchers={ 
      @Catch(targetCatchHandler=Bar.class,targetException=ArithmeticException.class),
      @Catch(targetCatchHandler=Bar.class,targetException=NullPointerException.class)})
  public void callMethod()throws Throwable {
    int a=0,b=10;
    System.out.println(b/a);
  }
  public static void main(String[] args) throws Exception {
    Foo foo=new Foo();
    MethodCaller.callMethod(foo);
  }
}

如你所见,用户必须通过 callmethod() 方法调用方法,你也可以省略 Caller 接口,并使用注解声明超过一个类中的一个方法需要一堆额外的代码.我希望我能伸出援手.

as you see, the user HAS TO call the methods by the callmethod() method, you would also omit the Caller interface, and use annotation to declare more than one method in a class that it needs a bunch of extra codez. I hope I could give some hand.

这篇关于使用注释进行异常处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆