用于包装方法的 Java 注释 [英] Java annotation for wrapping a method
问题描述
我有很多基本遵循这种模式的样板代码:
I have a lot of boilerplate code that basically follows this pattern:
function doSomething() {
try {
[implementation]
[implementation]
[implementation]
[implementation]
} catch (Exception e) {
MyEnv.getLogger().log(e);
} finally {
genericCleanUpMethod();
}
}
我很想创建我自己的注释来清理我的代码:
I'd love to create my own annotation to clean my code up a bit:
@TryCatchWithLoggingAndCleanUp
function doSomething() {
[implementation]
[implementation]
[implementation]
[implementation]
}
方法签名变化很大(取决于方法的实际实现),但样板文件 try/catch/finally 部分始终相同.
The method signatures vary wildly (depending on the actual implementation of the method), but the boilerplate try/catch/finally part is always the same.
我想到的注释会自动用整个try...catch...finally
hoopla 包装带注释方法的内容.
The annotation I have in mind would automatically wrap the contents of the annotated method with the whole try...catch...finally
hoopla.
我已经四处寻找一种简单的方法来做到这一点,但一无所获.我不知道,也许我只是看不到所有带注释的树木的树林.
I've searched high and low for a straightforward way to do this, but have found nothing. I don't know, maybe I just can't see the woods for all the annotated trees.
任何有关我如何实现此类注释的指示将不胜感激.
Any pointers on how I might implement such an annotation would be greatly appreciated.
推荐答案
要做到这一点,您需要一些 AOP 框架来在您的方法周围使用代理.该代理将捕获异常并执行 finally 块.坦率地说,如果你还没有使用支持 AOP 的框架,我不确定我是否会使用一个来保存这几行代码.
To do this, you would need some AOP framework that would use a proxy around your method. This proxy would catch the exception and execute the finally block. Quite frankly, if you don't use a framework supporting AOP already, I'm not sure I would use one just to save these few lines od code.
不过,您可以使用以下模式以更优雅的方式执行此操作:
You could use the following pattern to do this in a more elegant way, though:
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
作为接口,但你可以定义自己的 Command
接口:
I just used Callable<Void>
as an interface, but you could define your own Command
interface:
public interface Command {
public void execute() throws Exception;
}
从而避免使用通用 Callable
并从 Callable 返回 null 的需要.
and thus avoid the need to use a generic Callable<Void>
and return null from the Callable.
如果你想从你的方法中返回一些东西,那么让 logAndCleanup()
方法通用.这是一个完整的示例:
in case you want to return something from your methods, then make the logAndCleanup()
method generic. Here's a complete example:
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,包装的代码可以更漂亮一些:
EDIT : And with Java 8, the wrapped code can be a bit prettier :
public String doSomething(final boolean throwException) {
return logAndCleanup(() -> {
if (throwException) {
throw new Exception("you asked for it");
}
return "hello";
});
}
这篇关于用于包装方法的 Java 注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!