昨晚和@长篇小说 讨论 新版中的 Duang.duang(Class<T> targetClass, Interceptor... injectInters) 在Aop工具被移除的问题。然后看Aop的扩展都是放开的,就尝试的撸了一下代码,实现功能后,发现这个性能还是有影响的,但是如果使用合理的话,也不是不能接受。
思路:在Aop创建对象之前,对它里面插入Interceptor数组对象即可。
那么大致Java如下:
MyAop.java
package com.momathink.common.proxy; import com.jfinal.aop.Aop; import com.jfinal.aop.AopManager; import com.jfinal.aop.Interceptor; import com.jfinal.proxy.ProxyManager; /** * 扩展支持 inject interceptor */ public class MyAop { public static <T> T get(Class<T> targetClass) { return Aop.get(targetClass); } public static <T> T inject(T targetObject) { return Aop.inject(targetObject); } public static <T> T aop(Class<T> targetClass, Interceptor... injectInters) { aopFactory.remove(targetClass); proxyFactory.remove(targetClass); TL.set(injectInters); T ret; try { ret = get(targetClass); }finally { TL.remove(); } //考虑是否移除缓存remove return ret; } private static ThreadLocal<Interceptor[]> TL = new ThreadLocal(); private static MyProxyFactory proxyFactory = new MyProxyFactory(); private static MyAopFactory aopFactory = new MyAopFactory(); static Interceptor[] getInterceptors(){ return TL.get(); } public static void init(){ AopManager aopManager = AopManager.me(); aopManager.setAopFactory(aopFactory); ProxyManager proxyManager = ProxyManager.me(); proxyFactory.setProxyGenerator(new MyProxyGenerator()); proxyManager.setProxyFactory(proxyFactory); } }
MyAopFactory.java
package com.momathink.common.proxy; import com.jfinal.aop.AopFactory; public class MyAopFactory extends AopFactory { public void remove(Class<?> targetClass){ singletonCache.remove(targetClass); } }
MyProxyFactory.java
package com.momathink.common.proxy; import com.jfinal.proxy.ProxyClass; import com.jfinal.proxy.ProxyFactory; import com.jfinal.proxy.ProxyMethod; import java.util.List; import java.util.Objects; public class MyProxyFactory extends ProxyFactory { public void remove(Class target){ cache.remove(target); } protected void cacheMethodProxy(ProxyClass proxyClass) { if (Objects.nonNull(MyAop.getInterceptors())){ List<ProxyMethod> list = proxyClass.getProxyMethodList(); for (int i = 0; i < list.size(); i++) { MyProxyMethod method = intercept(list.get(i)); //提前存储,避免后面被MyAop释放了 method.getInterceptors(); list.set(i, method); } } super.cacheMethodProxy(proxyClass); } private MyProxyMethod intercept(ProxyMethod proxyMethod) { return new MyProxyMethod(proxyMethod); } }
MyProxyGenerator.java
package com.momathink.common.proxy; import com.jfinal.proxy.ProxyClass; import com.jfinal.proxy.ProxyGenerator; import java.lang.reflect.Method; import java.util.List; import java.util.Objects; public class MyProxyGenerator extends ProxyGenerator { protected boolean hasInterceptor(List<Class<?>> methodUpperInters, ProxyClass proxyClass, Method method) { if (Objects.nonNull(MyAop.getInterceptors())){ return true; } return super.hasInterceptor(methodUpperInters, proxyClass, method); } }
MyProxyMethod.java
package com.momathink.common.proxy; import com.jfinal.aop.Interceptor; import com.jfinal.proxy.ProxyMethod; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Objects; public class MyProxyMethod extends ProxyMethod { private ProxyMethod proxyMethod; private Interceptor[] interceptors = null; public MyProxyMethod(ProxyMethod proxyMethod) { this.proxyMethod = proxyMethod; } public Interceptor[] getInterceptors() { if (interceptors == null) { Interceptor[] a = MyAop.getInterceptors(); Interceptor[] b = proxyMethod.getInterceptors(); if (Objects.nonNull(a)){ ArrayList<Interceptor> list = new ArrayList<>(); list.addAll(Arrays.asList(a)); list.addAll(Arrays.asList(b)); interceptors = list.toArray(new Interceptor[list.size()]); }else{ interceptors = b; } } return interceptors; } public void setKey(long key) { proxyMethod.setKey(key); } public Long getKey() { return proxyMethod.getKey(); } public void setTargetClass(Class<?> targetClass) { proxyMethod.setTargetClass(targetClass); } public Class<?> getTargetClass() { return proxyMethod.getTargetClass(); } public void setProxyClass(Class<?> proxyClass) { proxyMethod.setProxyClass(proxyClass); } public Class<?> getProxyClass() { return proxyMethod.getProxyClass(); } public void setMethod(Method method) { proxyMethod.setMethod(method); } public Method getMethod() { return proxyMethod.getMethod(); } }
搞定!
测试:
TestInterceptor.java
package com.momathink.common.proxy; import com.jfinal.aop.Interceptor; import com.jfinal.aop.Invocation; public class TestInterceptor implements Interceptor { @Override public void intercept(Invocation inv) { System.out.println("TestInterceptor - 1"); inv.invoke(); System.out.println("TestInterceptor - 2"); } }
Test.java
package com.momathink.common.proxy; public class Test { public static void main(String[] args) { MyAop.init(); // Test.test(); System.out.println("------"); Test test = MyAop.get(Test.class); test.test(); System.out.println("------"); Test t = MyAop.aop(Test.class, new TestInterceptor()); t.test(); System.out.println("----2--"); //如果这个对象被多次调用,那么建议把t对象进行静态常量存储起来,避免多次创建生产性能严重损耗 //如果故意多次创建了,会是什么效果,这里试试 t = MyAop.aop(Test.class, new TestInterceptor()); t.test(); } public void test(){ System.out.println("test"); } }
好像是以前哪个效果。。。未严格测试,仅仅贴码讨论交流