1. Modèle d'agence
La soi-disant agence est une personne ou une organisation agissant au nom d'une autre personne ou d'une autre organisation. Dans certains cas, un client ne veut pas ou ne peut pas référencer directement un objet, et un objet proxy peut servir d'intermédiaire entre le client et l'objet cible.
Le mode proxy fournit un objet proxy pour un objet, et l'objet proxy contrôle la référence à l'objet d'origine.
Exemple tiré de la vie réelle : je suis occupé à faire des heures supplémentaires pendant le Nouvel An chinois et je n'ai pas le temps d'acheter des billets de train. À ce moment-là, je peux appeler la billetterie la plus proche et leur demander d'acheter un billet de train. Je rentre chez moi. Bien sûr, des frais de main-d'œuvre supplémentaires s'appliqueront. Mais il doit être clair que la billetterie elle-même ne vend pas de billets. Seule la gare vend réellement des billets. Les billets que la billetterie vous vend sont réellement vendus par l'intermédiaire de la gare. C'est très important !
Dans l'exemple ci-dessus, vous êtes le « client », la billetterie est le « rôle d'agent », la gare est le « rôle réel », et la vente de billets est appelée le « rôle abstrait » !
Exemple de code JAVA en mode proxy :
Rôle abstrait : classe ou interface abstraite
interface Business { void doAction(); }
Rôle réel : implémente véritablement l'interface de logique métier
Proxy Rôle : il n'implémente pas l'interface de logique métier, mais appelle le rôle réel à implémenter
class BusinessImplProxy implements Business { private BusinessImpl bi; public void doAction() { if (bi==null) { bi = new BusinessImpl(); } doBefore(); bi.doAction(); doAfter(); } public void doBefore() { System.out.println("前置处理!"); } public void doAfter() { System.out.println("后置处理!"); } } //测试类 class Test { public static void main(String[] args) { //引用变量定义为抽象角色类型 Business bi = new BusinessImplProxy(); bi.doAction(); } }
<span></span>
Par conséquent, avec le support de JVM, la classe proxy (« rôle d'agent ») peut être dynamiquement généré au moment de l'exécution), nous pouvons résoudre le problème de gonflement du code mentionné ci-dessus en mode proxy. Après avoir utilisé le proxy dynamique, le « rôle d'agent » ne sera pas généré manuellement. Au lieu de cela, la JVM spécifiera le chargeur de classe, le tableau d'interface et. gestionnaire d'appel au moment de l'exécution. 3 paramètres à générer dynamiquement.
Exemple de code JAVA en mode proxy dynamique :
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.lang.reflect.Method; //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类 interface BusinessFoo { void foo(); } interface BusinessBar { String bar(String message); } //真实角色:真正实现业务逻辑方法 class BusinessFooImpl implements BusinessFoo { public void foo() { System.out.println("BusinessFooImpl.foo()"); } } class BusinessBarImpl implements BusinessBar { public String bar(String message) { System.out.println("BusinessBarImpl.bar()"); return message; } } //动态角色:动态生成代理类 class BusinessImplProxy implements InvocationHandler { private Object obj; BusinessImplProxy() { } BusinessImplProxy(Object obj) { this.obj = obj; } public Object invoke(Object proxy,Method method,Object[] args) throws Throwable { Object result = null; doBefore(); result = method.invoke(obj,args); doAfter(); return result; } public void doBefore(){ System.out.println("do something before Business Logic"); } public void doAfter(){ System.out.println("do something after Business Logic"); } public static Object factory(Object obj) { Class cls = obj.getClass(); return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new BusinessImplProxy(obj)); } } //测试类 public class DynamicProxy { public static void main(String[] args) throws Throwable { BusinessFooImpl bfoo = new BusinessFooImpl(); BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bfoo); bf.foo(); System.out.println(); BusinessBarImpl bbar = new BusinessBarImpl(); BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar); String message = bb.bar("Hello,World"); System.out.println(message); } }
Description du flux du programme :
new BusinessFooImpl(); Créez un "vrai rôle" et transmettez-le à la méthode d'usine BusinessImplProxy.factory () , puis initialisez le "gestionnaire d'invocation" - la classe qui implémente InvocationHandler. Et renvoie une instance de classe proxy créée dynamiquement. Étant donné que le « rôle d'agent » doit également implémenter les méthodes de logique métier fournies par le « rôle abstrait », il peut être transformé en BusinessBar et affecté à la référence bb pointant vers le type BusinessBar. La méthode
newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h) permet aux programmeurs de spécifier des paramètres et de renvoyer dynamiquement la classe proxy requise, tandis que l'invocation (Object proxy, Method method, Object[] args) méthode Elle est appelée dynamiquement par la JVM au moment de l'exécution. Lors de l'exécution de la méthode "bb.bar("Hello,World");" la JVM attribue dynamiquement un "gestionnaire d'invocation", transmet les paramètres à l'invocation externe et appelle method.invoke(obj, args) pour l'exécuter !
La méthode statique BusinessImplProxy.Factory est utilisée pour générer dynamiquement des classes proxy (« rôles d'agent »). Les rôles proxy sont générés dynamiquement au moment de l'exécution en fonction de différentes interfaces de logique métier BusinessFoo et BusinessBar. Le « rôle abstrait », le « rôle d'agent » et le gestionnaire d'invocation (classe qui implémente l'interface InvocationHandler) peuvent tous être modifiés, le proxy dynamique de JAVA est donc très puissant.
Pour des explications plus détaillées sur le mode proxy Java et le mode proxy dynamique, veuillez faire attention au site Web PHP chinois !