JFinal使用技巧-Aop之Proxy 动态代理[DEBUG]演示

刷到微信群大家在讨论JF的aop.get(...class)和new区别,这里我觉得可以分享一下它们的区别。

之前有大佬分享过AOP代码的原理和依赖关系,大家可以在上方搜索框:AOP原理


ce4d34a3be0afc7a3e3d52ec407e21d.png

不多说,直 接 上 石马 ~
建几个测试类:

package com.jfinal.test.aop;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;

public class TestInterceptor implements Interceptor {
    public void intercept(Invocation inv) {
        String methodName = inv.getMethodName();
        System.out.println("开头 " + methodName);
        inv.invoke();
        System.out.println("结尾 " + methodName);
    }
}
package com.jfinal.test.aop;

import com.jfinal.aop.Before;

public class A {
    
    @Before(TestInterceptor.class)
    public void a(){
        System.out.println("test-a");
    }
}
package com.jfinal.test.aop;

import com.jfinal.aop.Aop;

public class TestAop {

    public static void main(String[] args) {
        A a = new A();
        System.out.println("生成A的子类Java代码-开始---------");
        A aj = Aop.get(A.class);
        System.out.println("生成A的子类Java代码-结束---------");

        System.out.println(a.getClass());
        System.out.println(aj.getClass());

        aj.a();
    }

}

好,来运行一下 TestAop的main方法 看效果:

d8ef8acc55735da4dbe566a090062a6.png

好,这个是aop.get(...class)执行的过程,和使用的效果。

那再来试试new的效果了?

package com.jfinal.test.aop;

public class TestAop {

    public static void main(String[] args) {
        A a = new A();
        a.a();
    }

}

image.png

可见是直接原始运行的a方法,并没有执行 TestInterceptor的代码,写了@Before(TestInterceptor.class)也是没用的。

image.png

区别到这里就很明显了,非JF创建的类,不用Aop.get(A.class)是不会执行Interceptor拦截器的。

-------------------------------------------------------------------------------

那么有人就问了,JF创建后的类,再new其他类,会不会有作用了?那么再来实验一下:
加一个B类:

package com.jfinal.test.aop;
import com.jfinal.aop.Before;
public class B {
    @Before(TestInterceptor.class)
    public void b(){
        System.out.println("test-b");
    }
}

A类来调用一下B类

package com.jfinal.test.aop;
import com.jfinal.aop.Before;
public class A {
    @Before(TestInterceptor.class)
    public void a(){
        System.out.println("test-a");
        new B().b();
    }
}
package com.jfinal.test.aop;

import com.jfinal.aop.Aop;

public class TestAop {

    public static void main(String[] args) {
        A a = new A();
        System.out.println("生成A的子类Java代码-开始---------");
        A aj = Aop.get(A.class);
        System.out.println("生成A的子类Java代码-结束---------");

        System.out.println(a.getClass());
        System.out.println(aj.getClass());

        aj.a();
    }

}

好,来运行一下 TestAop的main方法 看效果:
932479a4f4aac90fec384f34df98f11.png

可以看到,只要是new,拦截器是不会执行的。

那么想让它依赖执行,不想new,还想拦截器Interceptor起作用了?
https://jfinal.com/doc/4-5
使用 @Inject 注解,再看效果吧:
给A类加上注解:

package com.jfinal.test.aop;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
public class A {
    @Inject
    B b;
    @Before(TestInterceptor.class)
    public void a(){
        System.out.println("test-a");
        b.b();
    }
}

好,来运行一下 TestAop的main方法 看效果:

a25cf954a0223189830b3b96549ffce.png8d43e728390d00eb18e9e57b898dd8f.png

结果很明显了,得由JF创建,才能被代理。

项目中 业务类 如果不需要执行拦截器Interceptor时,确实new创建对象会更快的。
知道什么时候用,什么时候不用,才是真滴好~

小分享到这里就结束了~ 点个赞呗~

评论区

zhangtianxiao

2021-12-14 10:29

2L是methodKey, 定位Method好去call

JFinal

2021-12-14 13:25

@zhangtianxiao 对源码的了解已经相当深入,牛逼