Le proxy dynamique est en fait la classe java.lang.reflect.Proxy qui génère dynamiquement un octet de classe basé sur toutes les interfaces que vous spécifiez. Cette classe héritera de la classe Proxy et implémentera toutes les interfaces que vous spécifiez (le tableau d'interfaces que vous transmettez dans le paramètre). ) ; Utilisez ensuite le chargeur de classe que vous avez spécifié pour charger l'octet de classe dans le système, et enfin générer un objet d'une telle classe, et initialiser certaines valeurs de l'objet, telles que invocationHandler, qui sont les membres de la méthode correspondant à toutes les interfaces. . Après initialisation, l'objet est renvoyé au client appelant. De cette façon, le client obtient un objet proxy qui implémente toutes vos interfaces. Veuillez consulter l'exemple d'analyse :
interface publique BusinessProcessor {
public void processBusiness();
}
@Outrepasser
public void processBusiness() {
System.out.println("traitement des affaires....");
}
}
importer java.lang.reflect.InvocationHandler ;
importer java.lang.reflect.Method ;
/**
*Catégorie agence commerciale
* @auteur fanshadoop
*
*/
classe publique BusinessProcessorHandler implémente InvocationHandler {
cible d'objet privé = null ;
BusinessProcessorHandler (cible de l'objet) {
this.target = cible ;
}
appel d'objet public (proxy d'objet, méthode de méthode, arguments Object[])
lance Jetable {
Système.out
.println("Vous pouvez faire quelque chose ici avant de traiter votre affaire");
Résultat de l'objet = method.invoke(target, args);
Système.out
.println("Vous pouvez faire quelque chose ici après avoir traité votre entreprise");
renvoyer le résultat ;
}
}
importer java.lang.reflect.Field ;
importer java.lang.reflect.Method ;
importer java.lang.reflect.Modifier ;
importer java.lang.reflect.Proxy ;
Test de classe publique {
/**
* @param arguments
*/
public static void main (String[] arguments) {
BusinessProcessorImpl bpimpl = new BusinessProcessorImpl();
Gestionnaire BusinessProcessorHandler = new BusinessProcessorHandler(bpimpl);
BusinessProcessor bp = (BusinessProcessor) Proxy.newProxyInstance(
bpimpl.getClass().getClassLoader(), bpimpl.getClass()
.getInterfaces(), gestionnaire);
bp.processBusiness();
System.out.println(bp.getClass().getName());
printClassDefinition(bp.getClass());
}
public static String getModifier(int modificateur) {
Résultat de la chaîne = "" ;
commutateur (modificateur) {
Modificateur de casse.PRIVATE :
résultat = "privé" ;
modificateur de cas.PUBLIC :
résultat = "public" ;
modificateur de cas.PROTÉGÉ :
résultat = "protégé" ;
Modificateur de cas.RÉSUMÉ :
résultat = "abstrait" ;
Modificateur de cas.FINAL :
résultat = "final" ;
Modificateur de casse.NATIVE :
résultat = "natif" ;
Modificateur de cas.STATIC :
résultat = "statique" ;
Modificateur de cas. SYNCHRONISÉ :
résultat = "synchronisé" ;
Modificateur de casse.STRICT :
résultat = "strict" ;
Modificateur de cas.TRANSIENT :
résultat = "transitoire" ;
modificateur de cas.VOLATILE :
résultat = "volatile" ;
Modificateur de cas.INTERFACE :
résultat = "interface" ;
}
renvoyer le résultat ;
}
public static void printClassDefinition (Class clz) {
Chaîne clzModifier = getModifier(clz.getModifiers());
if (clzModifier != null && !clzModifier.equals("")) {
clzModifier = clzModifier + " ;
}
String superClz = clz.getSuperclass().getName();
if (superClz != null && !superClz.equals("")) {
superClz = "étend" + superClz ;
}
Class[] interfaces = clz.getInterfaces();
Chaîne inters = "" ;
pour (int i = 0; i < interfaces.length; i++) {
si (je == 0) {
inters += "implémente";
}
inters += interfaces[i].getName();
}
System.out.println(clzModifier + clz.getName() + " " + superClz + " "
+ inters);
System.out.println("{");
Champs Field[] = clz.getDeclaredFields();
pour (int i = 0; i < champs.longueur; i++) {
Modificateur de chaîne = getModifier(fields[i].getModifiers());
if (modifier != null && !modifier.equals("")) {
modificateur = modificateur + " " ;
}
Chaîne fieldName = field[i].getName();
Chaîne fieldType = champs[i].getType().getName();
System.out.println(" " + modificateur + fieldType + " " + fieldName
+ ";");
}
System.out.println();
Method[] méthodes = clz.getDeclaredMethods();
pour (int i = 0; i < méthodes.longueur; i++) {
Méthode méthode = méthodes[i];
Modificateur de chaîne = getModifier(method.getModifiers());
if (modifier != null && !modifier.equals("")) {
modificateur = modificateur + " " ;
}
String nom_méthode = méthode.getName();
Classe returnClz = method.getReturnType();
Chaîne retrunType = returnClz.getName();
Class[] clzs = method.getParameterTypes();
Chaîne paraListe = "(";
pour (int j = 0; j < clzs.length; j++) {
paraList += clzs[j].getName();
si (j != clzs.longueur - 1) {
paraListe += ", ";
}
}
paraListe += ")";
clzs = méthode.getExceptionTypes();
Exceptions de chaîne = "" ;
pour (int j = 0; j < clzs.length; j++) {
si (j == 0) {
exceptions += "lance" ;
}
exceptions += clzs[j].getName();
si (j != clzs.longueur - 1) {
exceptions += ", ";
}
}
exceptions += ";";
String methodPrototype = modificateur + retrunType + " " + methodName
+ paraListe + exceptions ;
System.out.println(" " + methodPrototype);
}
System.out.println("}");
}
}
booléen égal(java.lang.Object);
java.lang.String toString();
int hashCode();
void processBusiness();
}
Évidemment, la méthode Proxy.newProxyInstance fera les choses suivantes :
1. Générez dynamiquement une classe basée sur les interfaces du deuxième paramètre transmis pour implémenter l'interface dans les interfaces. Dans cet exemple, il s'agit de la méthode processBusiness de l'interface BusinessProcessor. Et il hérite de la classe Proxy et réécrit trois méthodes telles que hashcode, toString et equals. Pour une implémentation spécifique, veuillez vous référer à ProxyGenerator.generateProxyClass(...); Dans cet exemple, la classe $Proxy0 est générée
2. Chargez la classe nouvellement générée dans le jvm via le premier paramètre transmis, classloder. Sur le point de charger la classe $Proxy0
3. Utilisez le troisième paramètre pour appeler le constructeur $Proxy0 (InvocationHandler) de $Proxy0 pour créer un objet de $Proxy0, et utilisez le paramètre interfaces pour parcourir toutes ses méthodes d'interface et générer un objet Method pour initialiser plusieurs variables membres de méthode du objet.
4. Renvoyez l'instance de $Proxy0 au client.
Tout va bien maintenant. Voyons comment le client l'ajuste et cela deviendra clair.
1. Le client obtient l'objet instance de $Proxy0 Puisque $Proxy0 hérite de BusinessProcessor, il n'y a aucun problème à le convertir en BusinessProcessor.
BusinessProcessor bp = (BusinessProcessor)Proxy.newProxyInstance(....);
2. bp.processBusiness();
Ce qui est réellement appelé est $Proxy0.processBusiness(); alors l'implémentation de $Proxy0.processBusiness() consiste à appeler la méthode d'invocation via InvocationHandler !