Java注释包装方法

199 阅读2分钟

我有很多样板代码,基本上遵循以下模式:

function doSomething() {
  try {
    [implementation]
    [implementation]
    [implementation]
    [implementation]
  } catch (Exception e) {
    MyEnv.getLogger().log(e);
  } finally {
    genericCleanUpMethod();
  }
}

我很想创建自己的注释来稍微清理一下代码:

@TryCatchWithLoggingAndCleanUp
function doSomething() {
  [implementation]
  [implementation]
  [implementation]
  [implementation]
}

方法签名差别很大(取决于方法的实际实现),但是样板尝试/捕捉/最终部分总是相同的。

我所想到的注释将自动将带注释的方法的内容与整个try...catch...finally胡说八道。

我到处寻找一种直截了当的方法,但一无所获。我不知道,也许我只是看不见所有带注释的树的树林。

任何关于我如何实现这样一个注释的提示都将不胜感激。

要做到这一点,您需要一些AOP框架,它将在您的方法周围使用代理。此代理将捕获异常并执行Final块。坦率地说,如果您还没有使用支持AOP的框架,我不确定我是否会使用一个框架来保存这几行代码。

不过,您可以使用以下模式以更优雅的方式完成此操作:

public void doSomething() {
    logAndCleanup(new Callable<Void>() {
        public Void call() throws Exception {
            implementationOfDoSomething();
            return null;
        }
    });
}

private void logAndCleanup(Callable<Void> callable) {
    try {
        callable.call();
    }
    catch (Exception e) {
        MyEnv.getLogger().log(e);
    }
    finally {
        genericCleanUpMethod();
    }
}

我刚用Callable<Void>作为一个接口,但是您可以定义自己的Command接口:

public interface Command {
    public void execute() throws Exception;
}

从而避免了使用泛型Callable并从可调用中返回NULL。

编辑:如果您想从方法中返回某些内容,则将logAndCleanup()方法泛型。下面是一个完整的例子:

public class ExceptionHandling {
    public String doSomething(final boolean throwException) {
        return logAndCleanup(new Callable<String>() {
            public String call() throws Exception {
                if (throwException) {
                    throw new Exception("you asked for it");
                }
                return "hello";
            }
        });
    }

    public Integer doSomethingElse() {
        return logAndCleanup(new Callable<Integer>() {
            public Integer call() throws Exception {
                return 42;
            }
        });
    }

    private <T> T logAndCleanup(Callable<T> callable) {
        try {
            return callable.call();
        }
        catch (Exception e) {
            System.out.println("An exception has been thrown: " + e);
            throw new RuntimeException(e); // or return null, or whatever you want
        }
        finally {
            System.out.println("doing some cleanup...");
        }
    }

    public static void main(String[] args) {
        ExceptionHandling eh = new ExceptionHandling();

        System.out.println(eh.doSomething(false));
        System.out.println(eh.doSomethingElse());
        System.out.println(eh.doSomething(true));
    }
}

编辑:使用Java 8,包装的代码可能更漂亮一些:

public String doSomething(final boolean throwException) {
    return logAndCleanup(() -> {
        if (throwException) {
            throw new Exception("you asked for it");
        }
        return "hello";
    });
}