有没有办法使此代码有效?
LogonControl.java
@Audit(AuditType.LOGON) public void login(String username, String password) { // do login }
AuditHandler.java
public void audit(AuditType auditType) { // persist audit }
Endgame是,每次调用login()时,也会调用带有适当的audittype的audit()。
我想AOP可能是解决这个问题的方法,但是我希望它尽可能简单(我看过的AspectJ教程通常都有非常复杂的注释)。
注意:我不需要预先定义调用audit的方法,我正在为可扩展的框架编写它,而其他人可能需要使用它。
使用反射很容易,只需使用@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(); }
处理程序在哪里:
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())); } }
@测试:
Login login = LoginFactory.createLogin(); login.login("user", "secret"); login.logout();
输出:
叫人叫! 登录 登出