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?
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