有没有办法让这段代码有效?
LogonControl.java
@Audit(AuditType.LOGON)
public void login(String username, String password) {
// do login
}
AuditHandler.java
public void audit(AuditType auditType) {
// persist audit
}
结束游戏,每次调用login()时,也会调用audit(),并使用适当的audittype。
我想AOP可能是解决方案,但我希望它尽可能简单(我看过的AspectJ教程通常都有非常复杂的注释)。
注意:我不想预先定义将调用audit的方法,我是为可扩展框架编写的,其他人可能需要使用它。
答案 0 :(得分:15)
使用反射很容易用@Audit注释方法,就像JUnit中的测试运行器一样:
public interface Login {
void login(String name, String password);
}
public class LoginImpl implements Login {
@Audit(handler = LoginHandler.class)
public void login(String name, String password) {
System.out.println("login");
}
}
@Audit定义为:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {
Class<? extends Handler> handler();
}
Handler在哪里:
interface Handler {
void handle();
}
class LoginHandler implements Handler {
public void handle() {
System.out.println("HANDLER CALLED!");
}
}
现在是真正的代码:
public class LoginFactory {
private static class AuditInvocationHandler implements InvocationHandler {
private final Login realLogin;
public AuditInvocationHandler(Login realLogin) {
this.realLogin = realLogin;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Method realMethod = realLogin.getClass().getMethod(
method.getName(),
method.getParameterTypes());
Audit audit = realMethod.getAnnotation(Audit.class);
if (audit != null) {
audit.handler().newInstance().handle();
}
return method.invoke(realLogin, args);
}
}
public static Login createLogin() {
return (Login) Proxy.newProxyInstance(
LoginFactory.class.getClassLoader(),
new Class[]{Login.class},
new AuditInvocationHandler(new LoginImpl()));
}
}
@Test:
Login login = LoginFactory.createLogin();
login.login("user", "secret");
login.logout();
输出:
HANDLER CALLED! login logout
答案 1 :(得分:5)
如果你想要know how wheels work,或者如果你认为你可以做一些明显更轻的事情,那么滚动自己是有道理的。在你开始之前确保两者都是真的。
答案 2 :(得分:1)
查看Guice中的拦截方法:http://code.google.com/p/google-guice/wiki/AOP
类似的方法应该适用于任何AOP框架。