昨晚和@长篇小说 讨论 新版中的 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");
}
}
好像是以前哪个效果。。。未严格测试,仅仅贴码讨论交流