java - Kaedah dalaman CGLib asli boleh diproksikan apabila memanggil satu sama lain, tetapi Spring AOP berdasarkan CGLib gagal membuat proksi.
phpcn_u1582
phpcn_u1582 2017-07-03 11:43:34
0
1
1195

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_u1582
phpcn_u1582

membalas semua(1)
阿神

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

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan