Qu'est-ce qu'un proxy Java
Qu'est-ce qu'un proxy En fait, c'est facile à comprendre ? Il n'accède pas directement à la cible, mais est accessible via une couche intermédiaire, comme ceci :
Proxy statique de Java
Par exemple, si certains de nos fruits, comme les bananes, les pommes, etc., écrits en code Java, ressemblent probablement à ceci :(Tutoriel recommandé : tutoriel Java )
//Fruit.java/** * 水果的接口 */public interface Fruit { /** * 获取水果的名字 */ public String getName(); }//Apple.javapublic class Apple implements Fruit { @Override public String getName() { return "苹果"; } }//Banana.javapublic class Banana implements Fruit { @Override public String getName() { return "香蕉"; } }
//PeelFruitProxy.java/** * 代理,让每个水果去皮 */public class PeelFruitProxy implements Fruit { private Fruit mFruit; public PeelFruit(Fruit fruit) { this.mFruit = fruit; } @Override public String getName() { System.out.println("proxt:" + proxy.getClass().getName()); return "去皮的" + mFruit.getName(); } }
//Main.javapublic class Main { public static void main(String[] args) { Apple apple=new Apple();//原始的苹果 Banana banana=new Banana();//原始的香蕉 PeelFruitProxy peelApple=new PeelFruitProxy(apple);//代理,添加去皮功能 PeelFruitProxy peelBanana=new PeelFruitProxy(banana);//代理,添加去皮功能 System.out.println(peelApple.getName()); System.out.println(peelBanana.getName()); } }
Le proxy dynamique de Java
En Java, il existe une classe appelée Proxy qui fait cela, et vous pouvez directement utiliser la réflexion et l'interception du proxy. Commençons par présenter brièvement cette classe. En fait, la méthode statique la plus couramment utilisée est Proxt.newProxyInstance(), qui ressemble à ceci :public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
//FruitInvocationHandler.java/** * 调用方法拦截器 */public class FruitInvocationHandler implements InvocationHandler { private Fruit mFruit; public FruitInvocationHandler(Fruit fruit) { this.mFruit = fruit; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String result = (String) method.invoke(mFruit, args);//需要在这个方法里面,主动调用被代理的对象。 return "去皮的" + result; } }
//Main.Javapublic class Main { public static void main(String[] args) { Apple apple = new Apple(); Fruit proxyApple = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(apple)); System.out.println(proxyApple.getClass().getName()); System.out.println(proxyApple.getName()); Banana banana = new Banana(); Fruit proxyBanana = (Fruit) Proxy.newProxyInstance(Fruit.class.getClassLoader(), new Class[]{Fruit.class}, new FruitInvocationHandler(banana)); System.out.println(proxyApple.getClass().getName()); System.out.println(proxyBanana.getName()); } }
Procureur CGLib
cglib is a powerful, high performance and quality Code Generation Library, It is used to extend JAVA classes and implements interfaces at runtime.
//FruitMethodInterceptor.java/** * CGLib代理的方法拦截器 */public class FruitMethodInterceptor implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { String result = (String) proxy.invokeSuper(obj, args);//主要,这里调用的是父类,也就是说, 生成的类和原始类是继承关系 return "去皮的"+result; } }//Main.javapublic class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Apple.class); enhancer.setCallback(new FruitMethodInterceptor()); Apple apple = (Apple) enhancer.create(); System.out.println(apple.getClass().getName()); System.out.println(apple.getName()); } }
Résumé
Le premier type de proxy n'est pas mentionné ici. Il ne convient qu'à un proxy à interface unique et est décidé au moment de la compilation. Les deuxième et troisième types de proxys sont tous des proxys dynamiques, mais nous voyons qu'il existe des différences : 1) Le proxy dynamique du JDK ne peut implémenter que des proxys d'interface et est un objet proxy packagé (. instance de classe), c'est-à-dire que lors du processus proxy, il y a deux objets, un objet proxy et un objet cible. L'objet cible est empaqueté dans l'objet proxy. 2) Le proxy de CGLib hérite de l'objet cible, génère une nouvelle classe, puis implémente le proxy de cette façon, il y a un objet proxy dans la mémoire et aucun héritage direct n'est utilisé. La méthode génère des classes proxy au moment de l'exécution, ce qui est différent de javapoet qui génère des classes au moment de la compilation.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!