Maison  >  Article  >  Java  >  Explication détaillée du proxy statique, dynamique et du proxy dynamique CGLIB en Java (image)

Explication détaillée du proxy statique, dynamique et du proxy dynamique CGLIB en Java (image)

黄舟
黄舟original
2017-08-08 10:02:171493parcourir

Cet article présente principalement le proxy statique, le proxy dynamique et le résumé du proxy dynamique CGLIB en JAVA. Il a une certaine valeur de référence. Ceux qui sont intéressés peuvent en apprendre davantage

Le mode proxy est la conception la plus couramment utilisée. en Java L'un des modèles, particulièrement largement utilisé dans le framework Spring. Pour le mode proxy de Java, il peut généralement être divisé en : proxy statique, proxy dynamique et proxy dynamique CGLIB.

Les trois modes proxy ci-dessus seront expliqués séparément.

1. Proxy statique

Le proxy statique signifie en fait écrire la classe proxy de la méthode proxy à l'avance avant d'exécuter le programme, puis l'exécuter après la compilation. La classe existe déjà avant l'exécution du programme.
Ci-dessous, nous implémentons une démo de proxy statique :

Proxy statique

Définir une interface cible


package com.test.proxy;

public interface Target {

  public String execute();
}

TargetImpl implémente l'interface Target


package com.test.proxy;

public class TargetImpl implements Target {

  @Override
  public String execute() {
    System.out.println("TargetImpl execute!");
    return "execute";
  }
}

Classe proxy


package com.test.proxy;

public class Proxy implements Target{

  private Target target;

  public Proxy(Target target) {
    this.target = target;
  }

  @Override
  public String execute() {
    System.out.println("perProcess");
    String result = this.target.execute();
    System.out.println("postProcess");
    return result;
  }
}

Classe de test :


package com.test.proxy;

public class ProxyTest {

  public static void main(String[] args) {

    Target target = new TargetImpl();
    Proxy p = new Proxy(target);
    String result = p.execute();
    System.out.println(result);
  }

}

Résultat de l'exécution :


perProcess
TargetImpl execute!
postProcess
execute

Le proxy statique doit être spécifique Vers le proxy La classe proxy doit être écrite à l'avance. S'il existe de nombreuses méthodes proxy, il faudra écrire beaucoup de code. Par conséquent, les lacunes ci-dessus sont compensées par un proxy dynamique.

2. Proxy dynamique

Le proxy dynamique utilise principalement le mécanisme de réflexion pour générer dynamiquement la classe proxy requise au moment de l'exécution.

Proxy dynamique

Interface


package com.test.dynamic;

public interface Target {

  public String execute();
}

Classe d'implémentation


package com.test.dynamic;

public class TargetImpl implements Target {

  @Override
  public String execute() {
    System.out.println("TargetImpl execute!");
    return "execute";
  }
}

Classe proxy


package com.test.dynamic;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicProxyHandler implements InvocationHandler{

  private Target target;

  public DynamicProxyHandler(Target target) {
    this.target = target;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("========before==========");
    Object result = method.invoke(target,args);
    System.out.println("========after===========");
    return result;
  }
}

Classe de test


package com.test.dynamic;

import java.lang.reflect.Proxy;

public class DynamicProxyTest {

  public static void main(String[] args) {
    Target target = new TargetImpl();
    DynamicProxyHandler handler = new DynamicProxyHandler(target);
    Target proxySubject = (Target) Proxy.newProxyInstance(TargetImpl.class.getClassLoader(),TargetImpl.class.getInterfaces(),handler);
    String result = proxySubject.execute();
    System.out.println(result);
  }

}

Résultat de l'exécution :


========before==========
TargetImpl execute!
========after===========
execute

Qu'il s'agisse d'un proxy dynamique ou d'un leader statique, une interface doit être définie avant que la fonction proxy puisse être implémentée. Cela a également des limites, donc afin de résoudre ce problème, une troisième méthode de proxy a émergé : le proxy cglib.

3.cglib proxy

CGLib utilise une technologie de bytecode de très bas niveau. Le principe est de créer une sous-classe pour une classe via la technologie de bytecode, et la technologie d'interception de méthodes. est utilisé dans les sous-classes pour intercepter tous les appels aux méthodes de la classe parent et intégrer la logique transversale en conséquence. Le proxy dynamique JDK et le proxy dynamique CGLib constituent la base de la mise en œuvre de Spring AOP.

proxy dynamique cglib

Classe cible


package com.test.cglib;

public class Target {

  public String execute() {
    String message = "-----------test------------";
    System.out.println(message);
    return message;
  }
}

Classe proxy générique :


package com.test.cglib;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor{

  @Override
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    System.out.println(">>>>MethodInterceptor start...");
    Object result = proxy.invokeSuper(obj,args);
    System.out.println(">>>>MethodInterceptor ending...");
    return "result";
  }
}

Classe de test


package com.test.cglib;

import net.sf.cglib.proxy.Enhancer;

public class CglibTest {

  public static void main(String ... args) {
    System.out.println("***************");
    Target target = new Target();
    CglibTest test = new CglibTest();
    Target proxyTarget = (Target) test.createProxy(Target.class);
    String res = proxyTarget.execute();
    System.out.println(res);
  }

  public Object createProxy(Class targetClass) {
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(targetClass);
    enhancer.setCallback(new MyMethodInterceptor());
    return enhancer.create();
  }

}

Résultat de l'exécution :


***************
>>>>MethodInterceptor start...
-----------test------------
>>>>MethodInterceptor ending...
result

Le processus de génération de l'objet proxy est implémenté par la classe Enhancer. Les étapes approximatives sont les suivantes :

1. Générer le bytecode binaire de la classe proxy. Class ;

2. Chargez le bytecode binaire via Class.forName pour générer un objet Class

3. Obtenez la structure de l'instance via le mécanisme de réflexion et initialisez le proxy ; objet de classe.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn