recherche

Maison  >  Questions et réponses  >  le corps du texte

java - Les méthodes internes natives de CGLib peuvent être proxy lorsqu'elles s'appellent, mais Spring AOP basé sur CGLib ne parvient pas à proxy. Pourquoi?

Ce qui suit est la méthode d'écriture native de CGLib (implémentée à l'aide des classes du package 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();
    }
}

Le résultat imprimé est :
before fun1
before fun2
Vous pouvez voir que même si fun2() est appelé via foo.fun1(), fun()2 peut toujours être proxy.

Mais si vous utilisez la méthode d'écriture de base de 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();
    }
}

Le résultat de sortie est :
before fun1
fun2
On peut voir que la méthode fun2 n'est pas proxy.

Pourquoi y a-t-il une telle différence ?

phpcn_u1582phpcn_u15822726 Il y a quelques jours1199

répondre à tous(1)je répondrai

  • 阿神

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

    L'aop de Spring ne peut pas intercepter les appels de méthode internes. Spring signalera le bean de l'objet réel et le proxyBean après proxy a été amélioré avec des aspects :
    proxyBean est équivalent à :

    .

    avant

    invoquer(haricot,méthode)

    after
    De cette façon, fun2 est en fait appelé par le bean réel (invoke utilise l'objet réel pour exécuter la méthode que vous souhaitez exécuter), il n'y a donc pas d'effet avant.
    Lorsque vous utilisez réellement cglib, vous utilisez des beans proxy tout au long du processus

    répondre
    0
  • Annulerrépondre