Le mécanisme de réflexion Java et le proxy dynamique rendent Java plus puissant. Les concepts principaux de Spring IOC et AOP sont mis en œuvre par le mécanisme de réflexion et le proxy dynamique.
1 Réflexion Java
Exemple:
User user = new User (); user.setTime5flag ("test"); Classe <?> CLS = class.forname ("com.test.user"); // l'interface doit être publique, qu'elle soit utilisée en interne dans cette classe! Utilisez Cls.getDeclaredMethod (), soit Traverse pour modifier la méthode d'accessibilité Méthode = Cls.getMethod ("GetTime5Flag"); String res1 = (String) Method.Invoke (utilisateur); System.out.println (res1); // Si vous impliquez des types de base tels que int, utilisez int.class! Integer.class! = Int.class! méthode = cls.getMethod ("setTime5flag", string.class); Method.invoke (utilisateur, "roten"); méthode = cls.getMethod ("getTime5flag"); String Res2 = (String) Method.Invoke (User); System.out.println (Res2);Obtenez le package complet et le nom de classe via un objet:
user.getClass (). getName (); // Nom de la classe Full Path user.getClass (). getImpLename (); // Nom de classe sans nom de package
Obtenez des cours:
Class.forname ("com.test.user"); com.test.user.class; user.getClass (); Instancier un objet à travers la classeUtilisateur utilisateur = (utilisateur) cls.newinstance (); // il doit y avoir un constructeur de paramètreObtenez tous les constructeurs
Constructor <?> CONS [] = CLS.GetConstructors (); // return Cons [0] .newInstance () dans l'ordre de déclaration; // Pas de déclaration d'affichage, alors il y a un constructeur par défautObtenez toutes les interfaces implémentées par une classe
Classe <?> Ines [] = cls.getInterfaces ();Obtenez la classe parentale
ClS.getsuperclass ();Obtenez le modificateur
int mo = cls.getModifiers (); int mo = contre [0] .getModifiers (); int mo = method.getModifiers (); modificier.toString (mo);Obtenir les paramètres de la méthode
Method.getParameters (); CONS [0] .getParameters ();Obtenir le type de paramètre de la méthode
Method.getParameTortyTys (); CONS [0] .getParameTortyTys ();Obtenez tous les types d'exceptions lancés par la déclaration de la méthode
Method.getExceptionTypes ();Faire déclarer toutes les propriétés dans cette classe
Champ [] field = cls.getDeclaredFields (); // inclut PrivateField [0] .getModificaires (); champ [0] .getType ();
Obtenez tous les attributs publics de cette classe, y compris la déclaration de classe des parents, la déclaration d'interface et tous les attributs publics de cette déclaration de classe
Cl.getFields ();
Définissez l'attribut spécifié à l'accès
field.setAccessible (true); field.set (obj, 'ces'); field.get (obj);
* La différence entre getFields () et GetDeclaredFields (): getFields () ne peut accéder qu'à des champs déclarés publics dans la classe. Il ne peut pas accéder aux champs privés et peut accéder aux domaines publics hérités des autres classes. GetDeclaredFields () peut accéder à tous les champs de la classe, ce qui n'a rien à voir avec le public, le privé et la protection, mais ne peut pas accéder aux champs hérités des autres classes.
* La différence entre getMethods () et getDeclaredMethods (): getMethods () ne peut accéder qu'à des méthodes déclarées publiques dans la classe, et les méthodes privées ne sont pas accessibles et peuvent accéder aux méthodes publiques héritées à partir d'autres classes; GetDeclaredMethods () peut accéder à tous les champs de la classe, ce qui n'a rien à voir avec le public, le privé et la protection, et ne peut pas accéder aux méthodes héritées d'autres classes.
* La différence entre getConstructors () et GetDeclaredConstructors (): getConstructors () ne peut accéder aux constructeurs que les constructeurs déclarés publics dans la classe; GetDeclaredConstructors () peut accéder à tous les constructeurs de la classe et n'a rien à voir avec le public, le privé et la protection.
Obtenez et modifiez les informations du tableau par réflexion
int [] temp = {1,2,3,4,5}; class <?> Demo = temp.getClass (). getComponentType (); System.out.println ("Type de tableau:" + demo.getName ()); // INTSYSTEM.out.println ("Array Longueur:" + ArrayLegth (Temp); // 5System. du tableau: "+ array.get (temp, 0)); // 1Array.set (temp, 0, 100); System.out.println (" Le premier élément du tableau après modification est: "+ array.get (temp, 0)); // 100 Obtenez le type de tableauCl.getComponentType ();Déterminez s'il s'agit d'un type de tableau
Cl.isArray ();
2 agent Java
Le modèle proxy est un modèle de conception Java couramment utilisé. Sa caractéristique est que la classe proxy et la classe de délégués ont la même interface. La classe proxy est principalement responsable de la prétraitement des messages, du filtrage des messages, du transfert des messages à la classe du délégué et du traitement des messages après l'événement. Il existe généralement une association entre la classe proxy et la classe du délégué. L'objet d'une classe de proxy est associé à l'objet d'une classe de délégué. L'objet de la classe proxy lui-même n'implémente pas vraiment le service, mais fournit des services spécifiques en appelant les méthodes pertinentes de l'objet de classe de délégué.
Selon la période de création d'agent, les classes d'agent 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, puis le compile. Avant que le programme ne s'exécute, le fichier .class de la classe proxy existe déjà.
• Proxy dynamique: lorsque le programme est en cours d'exécution, ByteCode est généré dynamiquement par le mécanisme de réflexion Java.
2.1 Proxy statique
Count d'interface publique {public void queryCount ();} classe publique CountIMPL implémente le nombre {public void queryCount () {System.out.println ("Afficher la méthode du compte ..."); }} // Classe de proxy classe publique CountProxy implémente le nombre {private countImpl countImpl; public countProxy (countImpl countImpl) {this.CountImpl = countImpl; } @Override public void queryCount () {System.out.println ("avant le traitement des transactions"); countImpl.QueryCount (); // appelle la méthode de la classe du délégué; System.out.println ("après le traitement des transactions"); }} // classe de test public classe publique testCount {public static void main (String [] args) {countImpl countImpl = new countImpl (); CountProxy countProxy = new CountProxy (countImpl); countProxy.QueryCount (); }}Observez le code et constatez que chaque classe proxy ne peut servir qu'une seule interface, afin que trop de proxy se produisent inévitablement dans le développement de programmes. De plus, toutes les opérations proxy, à l'exception des différentes méthodes d'appel, toutes les autres opérations sont les mêmes, donc le code doit être répété pour le moment. La meilleure façon de résoudre ce problème est de remplir toutes les fonctions de proxy via une classe de proxy, donc elle doit être effectuée en utilisant un proxy dynamique pour le moment.
2.2 Agent dynamique
Le bytecode de la classe de proxy dynamique est généré dynamiquement par le mécanisme de réflexion Java lorsque le programme est exécuté, sans avoir besoin que les programmeurs écrivent manuellement son code source. Les classes de proxy dynamiques simplifient non seulement la programmation, mais améliorent également l'évolutivité des systèmes logiciels, car le mécanisme de réflexion Java peut générer tout type de classes de proxy dynamiques.
2.2.1 Proxy dynamique JDK
Les interfaces de classe proxy et invocationHandler dans le package java.lang.reflect offrent la possibilité de générer des classes proxy dynamiques.
Interface InvocationHandler:
Interface publique InvocationHandler {
L'objet public invoque (proxy d'objet, méthode de la méthode, objet [] args) lance Throwsable;
}
Description du paramètre:
Proxy d'objet: fait référence à l'objet proxyé.
Méthode Méthode: la méthode à appeler
Objet [] args: les paramètres requis lors de l'appel de la méthode
Vous pouvez considérer une sous-classe de l'interface InvocationHandler comme la classe d'opération finale d'un proxy, remplaçant ProxySubject.
Classe de procuration:
La classe de proxy est une classe d'opération spécialisée dans le proxy. Il peut générer dynamiquement des classes d'implémentation pour une ou plusieurs interfaces via cette classe. Cette classe fournit les méthodes de fonctionnement suivantes:
Objet statique public NewProxyInstance (Classloader Loader, Class <?> [] Interfaces, InvocationHandler h) lève illégalArgumentException
Description du paramètre:
Chargeur de chargeur de classe: chargeur de classe
Classe <?> [] Interfaces: Obtenez toutes les interfaces
InvocationHandler H: Obtenez l'instance de sous-classe de l'interface InvocationHandler
Si vous souhaitez terminer un proxy dynamique, vous devez d'abord définir une sous-classe de l'interface InvocationHandler pour compléter le fonctionnement spécifique du proxy.
INTERFACE SUJET {public String Says (String Name, int Age);} classe RealSubject implémente le sujet {@Override public String Says (Nom de la chaîne, int Age) {Nom de retour + "" + Age; }} // JDK dynamic proxy class MyInvocationHandler implémente invocationHandler {private Object Target = null; // lie l'objet délégué et renvoie une classe proxy de la classe publique bind (objet cible) {this. cible = cible; return proxy.newProxyInstance (target.getClass (). getClassLoader (), target.getClass (). getInterfaces (), this); // lie l'interface (CGLIB le compense)} @Override Public Object Invoke (Proxy d'objet, méthode de la méthode, objet [] args) lance Throwables {System.out.println ("avant la méthode!"); Objet temp = méthode.invoke (cible, args); System.out.println ("After Method!"); Tempère de retour; }} classe Hello {public static void main (String [] args) {MyInvocationHandler Demo = new MyInvocationHandler (); Sujet sub = (sujet) Demo.Bind (new realSubject ()); String info = sub.say ("Rollen", 20); System.out.println (info); }} Cependant, le proxy dynamique de JDK repose sur l'implémentation de l'interface. Si certaines classes n'implémentent pas les interfaces, ils ne peuvent pas utiliser le proxy JDK, ils doivent donc utiliser CGLIB dynamic proxy.
2.2.2 Proxy dynamique CGLIB
Le mécanisme proxy dynamique de JDK ne peut que des classes de proxy qui implémentent les interfaces, tandis que les classes qui n'implémentent pas les interfaces ne peuvent pas implémenter le proxy dynamique de JDK.
CGLIB implémente le proxy pour les classes. Son principe est de générer une sous-classe pour la classe cible spécifiée et de remplacer l'amélioration de la mise en œuvre de la méthode. Cependant, parce que l'héritage est utilisé, la classe modifiée finale ne peut pas être procassée.
Interface publique bookFacade {public void addbook (); } classe publique bookfacadeIMPL1 {public void addbook () {System.out.println ("Méthode ordinaire pour ajouter des livres ..."); }} import java.lang.reflect.method; importer net.sf.cglib.proxy.enhancer; importer net.sf.cglib.proxy.MethodInterceptor; importer net.sf.cglib.proxy.methodproxy; // CGLIB dynamic proxy classe publique classe publique BookFacadeCglib implémente MethodInterceptor {Target d'objet privé; // lie l'objet de délégué et renvoyez une classe proxy public objet GetInstance (objet Target) {this.target = cible; Enhancer Enhancer = New Enhancer (); Enhancer.SetSuperclass (this.target.getClass ()); // Méthode de rappel Enhancer.SetCallback (this); // Créer un objet proxy return Enhancer.create (); } @Override // Méthode de rappel Intercept de l'objet public (objet Obj, méthode de la méthode, objet [] args, méthodeproxy proxy) lance throwable {System.out.println ("fonction start"); Objet temp = proxy.invokesuper (obj, args); System.out.println ("Fonction End"); Tempère de retour; }} classe publique TestCglib {public static void main (String [] args) {bookfacadecglib cglib = new bookfacadecglib (); BookFacadeImpl1 bookCglib = (bookFacadeImpl1) cglib.getInstance (new BookFacadeImpl1 ()); bookcglib.addbook (); }}La brève discussion ci-dessus sur la réflexion et le proxy Java est tout le contenu que je partage avec vous. J'espère que vous pourrez vous faire référence et j'espère que vous pourrez soutenir Wulin.com plus.