Rumah  >  Soal Jawab  >  teks badan

java - Kaedah dalaman CGLib asli boleh diproksikan apabila memanggil satu sama lain, tetapi Spring AOP berdasarkan CGLib gagal membuat proksi.

Berikut ialah kaedah penulisan asli CGLib (dilaksanakan menggunakan kelas dalam pakej net.sf.cglib.proxy.*)

class Foo {
    public void fun1(){
        System.out.println("fun1");
        fun2();
    }
    public void fun2() {
        System.out.println("fun2");
    }
}

class CGlibProxyEnhancer implements MethodInterceptor{
    public Object getProxy(Class clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.print("before ");
        Object result = proxy.invokeSuper(obj,args);
        return result;
    }
}

public class Test {
    public static void main(String[] args) {
        CGlibProxyEnhancer pf = new CGlibProxyEnhancer();
        Foo foo = (Foo) pf.getProxy(Foo.class);
        foo.fun1();
    }
}

Hasil cetakan ialah:
sebelum fun1
sebelum fun2
Anda boleh lihat walaupun fun2() dipanggil melalui foo.fun1(), fun()2 masih boleh diproksikan.

Tetapi jika anda menggunakan kaedah penulisan asas Spring AOP:

class Foo {
    public void fun1() {
        System.out.println("fun1");
        fun2();
    }
    public void fun2() {
        System.out.println("fun2");
    }
}
class Before implements MethodBeforeAdvice {

    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.print("before ");
    }
}

public class TestCGLib {
    public static void main(String[] args) {
        Foo foo = new Foo();
        BeforeAdvice advice = new Before();
        ProxyFactory pf = new ProxyFactory();
        pf.setOptimize(true);//启用Cglib2AopProxy创建代理
        pf.setProxyTargetClass(true);
        pf.setTarget(foo);
        pf.addAdvice(advice);
        Foo proxy = (Foo) pf.getProxy();
        proxy.fun1();
    }
}

Hasil output ialah:
sebelum fun1
fun2
Dapat dilihat kaedah fun2 tidak diproksi.

Kenapa ada perbezaan sebegitu?

phpcn_u1582phpcn_u15822664 hari yang lalu1149

membalas semua(1)saya akan balas

  • 阿神

    阿神2017-07-03 11:45:34

    Aop Spring tidak boleh memintas panggilan kaedah dalaman Spring akan melaporkan kacang objek sebenar dan proksiBean selepas proksi telah dipertingkatkan dengan aspek:
    proxyBean bersamaan dengan:

    .

    sebelum

    seruan(kacang,kaedah)

    selepas
    Dengan cara ini, fun2 sebenarnya dipanggil oleh kacang sebenar (invoke menggunakan objek sebenar untuk melaksanakan kaedah yang anda ingin laksanakan), jadi tiada kesan sebelum.
    Apabila anda benar-benar menggunakan cglib, anda menggunakan kacang proksi sepanjang proses

    balas
    0
  • Batalbalas