JFinal使用技巧-记得什么是duang~duang~duang吗

昨晚和@长篇小说 讨论 新版中的 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");
    }
}

image.png

好像是以前哪个效果。。。未严格测试,仅仅贴码讨论交流

评论区

陈伟

2021-09-25 18:04

超级碗🏈非常实用的技术!!!赞一个!!!

zzutligang

2021-09-26 00:46

厉害厉害!必须赞一个!

happyboy

2021-10-13 09:03

是不是比pa~pa~pa还带劲。