Les classes de proxy dynamique Java peuvent être divisées en deux types.
Proxy statique: créé par les programmeurs ou génère automatiquement le code source par des outils spécifiques et le compile. Avant que le programme ne s'exécute, le fichier .class de la classe proxy existe déjà.
Proxy dynamique: il est créé dynamiquement à l'aide d'un mécanisme de réflexion lorsque le programme est en cours d'exécution.
1. Premièrement, nous démontrerons le proxy dynamique Java.
Nous avons maintenant une interface commerciale simple disant, comme suit:
La copie de code est la suivante:
Package TestAop;
interface publique disant {
public void sayshello (nom de chaîne);
public void Talking (nom de la chaîne);
}
Une classe d'implémentation simple disantIMPL, comme suit:
La copie de code est la suivante:
Package TestAop;
classe publique disant implémente implémente en disant {
@Outrepasser
public void sayshello (nom de chaîne) {
// Talage de méthode générée automatiquement de TODO
System.out.println (nom + ": Bonjour à tous!");
}
@Outrepasser
public void Talking (nom de la chaîne) {
// Talage de méthode générée automatiquement de TODO
System.out.println (nom + ": Je veux dire, nous devons travailler dur pour construire une société harmonieuse!");
}
}
Ce que nous voulons réaliser, c'est implanter dynamiquement le traitement avant et après avoir dit et parler.
JDK Dynamic Proxy utilise principalement deux classes dans le package java.lang.reflect: proxy et invocationHandler.
InvocationHandler est une interface qui définit la logique de coupe croisée en implémentant cette interface et appelle le code de la classe cible via un mécanisme de réflexion, tisse dynamiquement la logique de coupe et la logique métier.
Proxy utilise InvocationHandler pour créer dynamiquement une instance conforme à une certaine interface et génère un objet proxy de la classe cible.
Comme suit, nous créons une instance InvocationHandler:
La copie de code est la suivante:
Package TestAop;
import java.lang.reflect.invocationhandler;
import java.lang.reflect.method;
classe publique MyInvocationHandler implémente InvocationHandler {
cible d'objet privé;
MyInvocationHandler (cible d'objet) {
this.target = cible;
}
@Outrepasser
Invoque d'objet public (proxy d'objet, méthode de la méthode, objet [] args)
lance jetable {
// exécuter avant la méthode cible
System.out.println ("` `` `` `` `` `'' '' '' '' '' '' '' '');
System.out.println ("Veuillez parler sur scène la personne suivante!");
// Appel de méthode cible
Objet obj = méthode.invoke (cible, args);
// exécuter la méthode cible après
System.out.println ("Tout le monde applaudir et encouragement!");
retour obj;
}
}
Voici le test:
La copie de code est la suivante:
Package TestAop;
import java.lang.reflect.proxy;
classe publique jdkproxytest {
public static void main (String [] args) {
// La catégorie commerciale cible que vous souhaitez être agencé
Dire cible = new SayImll ();
// tisse la classe cible et la classe croisée ensemble
MyInvocationHandler Handler = new MyInvocationHandler (Target);
// Créer une instance proxy
Dire proxy = (dire) proxy.newproxyinstance (
Target.getClass (). GetClassOader (), // Le chargeur de classe de la classe Target
Target.getClass (). getInterfaces (), // Interfaces de la classe cible
Handler); // Classe croisée
proxy.sayhello ("Xiao Ming");
proxy.talking ("Xiaoli");
}
}
L'opération est la suivante:
La copie de code est la suivante:
―Vision - are
Veuillez parler sur scène la prochaine personne!
Xiao Ming: Bonjour à tous!
Tout le monde a applaudi et encouragé!
―Vision - are
Veuillez parler sur scène la prochaine personne!
Xiaoli: Je veux dire, nous devons travailler dur pour construire une société harmonieuse!
Tout le monde a applaudi et encouragé!
Il existe une grande limitation à l'utilisation du proxy dynamique JDK, c'est-à-dire qu'il nécessite que la classe cible doit implémenter l'interface de la méthode correspondante, et il ne peut créer que des instances de proxy pour l'interface. Nous pouvons voir dans la méthode de la procuration NewProxyInstance dans la classe de test ci-dessus que le deuxième paramètre de cette méthode est l'interface de la classe cible. Si cette classe n'implémente pas d'interface, elle dépend du proxy dynamique CGLIB.
CGLIB adopte la technologie Bytecode très sous-jacente, qui peut créer une sous-classe pour une classe, et utiliser des techniques d'interception de la méthode dans la sous-classe pour intercepter tous les appels de méthodes de classe parent et implanter la logique de coupe croisée dans la situation.
2. Ensuite, nous démontrerons le proxy dynamique CGLIB.
Tout d'abord, nous devons guider le package.
Nous créons d'abord un créateur proxy cglibproxy:
La copie de code est la suivante:
Package TestAop.cglib;
import java.lang.reflect.method;
importer net.sf.cglib.proxy.enhancer;
importer net.sf.cglib.proxy.MethodInterceptor;
importer net.sf.cglib.proxy.methodproxy;
classe publique Cglibproxy implémente MethodInterceptor {
Enhancer Enhancer = New Enhancer ();
objet public getProxy (class Clazz) {
// Définissez la sous-classe à créer
Enhance.SetSuperclass (Clazz);
Enhancer.setCallback (this);
// Créer dynamiquement des instances de sous-classe via la technologie bytecode
return Enhancer.Create ();
}
@Outrepasser
Interception d'objet public (objet obj, méthode de la méthode, objet [] args,
MethodProxy Proxy) lève le jetable {
// Talage de méthode générée automatiquement de TODO
System.out.println ("` `` `` `` `` `'' '' '' '' '' '' '' '');
System.out.println ("Veuillez parler sur scène la personne suivante!");
// Appel de méthode cible
Objet résultat = proxy.invokesuper (obj, args);
// exécuter la méthode cible après
System.out.println ("Tout le monde applaudir et encouragement!");
Résultat de retour;
}
}
Puis tester:
La copie de code est la suivante:
Package TestAop.cglib;
importer testaop.saying;
Importer TestAop.SayingImpl;
classe publique cglibproxytest {
public static void main (String [] args) {
CGLIBProxy proxy = new Cglibproxy ();
// Créer des classes proxy en générant dynamiquement des sous-classes
Dire cible = (dire) proxy.getProxy (SayImpl.class);
Target.sayhello ("Xiao Ming");
Target.talking ("Xiaoli");
}
}
Le résultat n'est pas différent du proxy dynamique JDK.
Le proxy dynamique JDK et le proxy dynamique CGLIB sont tous deux des améliorations d'exécution, qui sont améliorées en implantant du code croisé en classes de proxy. Contrairement à cela, AspectJ, qui peut implanter le code croisé dans la période de compilation via un compilateur spécial.