你也许用过大名鼎鼎的JOOQ,该项目git主页上也有个joor仓库,里面设计了一种非常方便的java反射API。
地址:https://github.com/jOOQ/jOOR
看一些例子:
/** * @see https://github.com/jOOQ/jOOR */ @Test public void test_simple_example() { Reflect reflectForString = Reflect.on(String.class).create("Hello doctor who"); String world = reflectForString.call("substring", 6).call("toString").get(); assertThat(world, equalTo("doctor who")); }
joor也给出了一个访问java.lang.reflect.Proxy API的方法:
例如:
@Test public void test_proxy_abstraction() { String substring = Reflect.on(String.class).create("doctor").as(StringProxy.class).substring(1); assertThat(substring, equalTo("octor")); } interface StringProxy { String substring(int beginIndex); }
那么AOP切面如何实现呢。
我改动以下这个方法:
@SuppressWarnings("unchecked") public <P, T> P as(Class<P> proxyType, Consumer<T> before, Consumer<T> after, T t) { final boolean isMap = (object instanceof Map); final InvocationHandler handler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); // Actual method name matches always come first try { before.accept(t); Object result = on(object).call(name, args).get(); after.accept(t); return result; } // [#14] Simulate POJO behaviour on wrapped map objects catch (ReflectException e) { if (isMap) { Map<String, Object> map = (Map<String, Object>) object; int length = (args == null ? 0 : args.length); if (length == 0 && name.startsWith("get")) { return map.get(property(name.substring(3))); } else if (length == 0 && name.startsWith("is")) { return map.get(property(name.substring(2))); } else if (length == 1 && name.startsWith("set")) { map.put(property(name.substring(3)), args[0]); return null; } } throw e; } } }; return (P) Proxy.newProxyInstance(proxyType.getClassLoader(), new Class[] { proxyType }, handler); }
利用java8的函数式,实现aop。
例子:
@Test public void test_aop() { com.doctor.org.joor.Reflect.on(Person.class).create().as(Pepole.class, t -> { System.out.println("before...."); }, t -> { System.out.println("after...."); }, null).doWalk(); }
interface Pepole { void doWalk(); void doEate(); } static class Person implements Pepole { private String name = "doctor who"; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public void doWalk() { System.out.println(name + " do walk"); } @Override public void doEate() { System.out.println(name + " do eate"); } }
输出:
before.... doctor who do walk after....