使用反射很容易,只需使用@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();输出:
叫人叫!登录登出



