Tout d’abord, expliquons brièvement ce qu’est le mode proxy.
Le proxy est un modèle de conception qui fournit un autre moyen d'accéder à l'objet cible?; c'est-à-dire d'accéder à l'objet cible via l'objet proxy. L'avantage est qu'il peut améliorer l'objet cible en fonction de l'implémentation de. l'objet cible. Opérations fonctionnelles supplémentaires, c'est-à-dire étendre les fonctions de l'objet cible.
Une idée en programmation est utilisée ici : ne modifiez pas le code ou les méthodes que d'autres ont écrits à volonté. , vous pouvez l'étendre via un proxy. Méthode
Donnez un exemple pour illustrer le r?le d'un agent : Supposons que nous voulions inviter une star, alors nous ne contactons pas directement la star, mais contactons l'agent de la star pour atteindre le même objectif. La star est un objet cible, il n'a qu'à être responsable du programme lors de l'événement, et d'autres questions insignifiantes sont laissées à son agent (courtier) pour résoudre. C'est un exemple de pensée d'agence dans la réalité <.>
Le schéma est le suivant :Simulez l'action de sauvegarde, définissez une interface pour l'action de sauvegarde?: IUserDao.java, puis l'objet cible implémente la méthode. UserDao.java de cette interface. à l'heure actuelle, si vous utilisez la méthode proxy statique, vous devez dans l'objet proxy (UserDaoProxy.java) Il implémente également l'interface IUserDao Lors de l'appel, appelez l'objet cible en appelant la méthode de. l'objet proxy.
Il est à noter que l'objet proxy et l'objet cible doivent implémenter la même interface, puis appeler la méthode de l'objet cible en appelant la même méthode
Interface?: IUserDao.java
/** * 接口 */public interface IUserDao { void save(); }Objet cible?: UserDao.java
/** * 接口實(shí)現(xiàn) * 目標(biāo)對(duì)象 */public class UserDao implements IUserDao { public void save() { System.out.println("----已經(jīng)保存數(shù)據(jù)!----"); } }Objet proxy?: UserDaoProxy.java
/** * 代理對(duì)象,靜態(tài)代理 */public class UserDaoProxy implements IUserDao{ //接收保存目標(biāo)對(duì)象 private IUserDao target; public UserDaoProxy(IUserDao target){ this.target=target; } public void save() { System.out.println("開始事務(wù)..."); target.save();//執(zhí)行目標(biāo)對(duì)象的方法 System.out.println("提交事務(wù)..."); } }(Partage de vidéos d'apprentissage?:
vidéo java tutoriel)
Classe de test : App.java/** * 測(cè)試類 */public class App { public static void main(String[] args) { //目標(biāo)對(duì)象 UserDao target = new UserDao(); //代理對(duì)象,把目標(biāo)對(duì)象傳給代理對(duì)象,建立代理關(guān)系 UserDaoProxy proxy = new UserDaoProxy(target); proxy.save();//執(zhí)行的是代理的方法 } }Résumé du proxy statique :
1 Cela peut être fait sans modifier la cible Sous la prémisse de la fonction de l'objet. , la fonction cible est étendue.
2. Inconvénients?:
1. L'objet proxy n'a pas besoin d'implémenter l'interface
2 La génération de l'objet proxy consiste à utiliser l'API du JDK. pour construire dynamiquement l'objet proxy dans la mémoire (il faut préciser la création de l'objet proxy /Le type d'interface implémenté par l'objet cible)
3. Le proxy dynamique est aussi appelé : proxy JDK, proxy d'interface
Le package où se trouve la classe proxy : java.lang.reflect .Proxy
JDK n'a besoin que d'utiliser la méthode newProxyInstance pour implémenter le proxy, mais cette méthode doit recevoir trois paramètres. La méthode d'écriture complète est :
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )Notez que cette méthode est une méthode statique dans la classe Proxy et re?oit Les trois paramètres sont : Chargeur ClassLoader, : spécifie que la cible actuelle l'objet utilise un chargeur de classe, et la méthode d'obtention du chargeur est fixe Class>[] interfaces,?: target Le type d'interface implémenté par l'objet, utilisez des génériques pour confirmer le type
InvocationHandler h?: traitement des événements, lors de l'exécution de la méthode de l'objet cible, la méthode du processeur d'événements sera déclenchée, et la méthode de l'objet cible actuellement exécuté sera utilisée comme paramètre Pass in exemple de code?:
classe d'interface IUserDao.java et classe d'implémentation d'interface. L'objet cible UserDao est le même sans modification. Sur cette base, ajoutez une classe de fabrique proxy (ProxyFactory.java), écrivez la classe proxy ici, puis. établissez d'abord la connexion entre l'objet cible et l'objet proxy dans la classe de test (le code qui doit utiliser le proxy), puis utilisez la méthode du même nom dans l'objet proxy
/** * 創(chuàng)建動(dòng)態(tài)代理對(duì)象 * 動(dòng)態(tài)代理不需要實(shí)現(xiàn)接口,但是需要指定接口類型 */public class ProxyFactory{ //維護(hù)一個(gè)目標(biāo)對(duì)象 private Object target; public ProxyFactory(Object target){ this.target=target; } //給目標(biāo)對(duì)象生成代理對(duì)象 public Object getProxyInstance(){ return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("開始事務(wù)2"); //執(zhí)行目標(biāo)對(duì)象方法 Object returnValue = method.invoke(target, args); System.out.println("提交事務(wù)2"); return returnValue; } } ); } }Classe de test?: App.java
/** * 測(cè)試類 */public class App { public static void main(String[] args) { // 目標(biāo)對(duì)象 IUserDao target = new UserDao(); // 【原始的類型 class cn.itcast.b_dynamic.UserDao】 System.out.println(target.getClass()); // 給目標(biāo)對(duì)象,創(chuàng)建代理對(duì)象 IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance(); // class $Proxy0 內(nèi)存中動(dòng)態(tài)生成的代理對(duì)象 System.out.println(proxy.getClass()); // 執(zhí)行方法 【代理對(duì)象】 proxy.save(); } }Résumé?:
L'objet proxy n'a pas besoin d'implémenter l'interface, mais l'objet cible doit implémenter l'interface, sinon dynamique le proxy ne peut pas être utilisé
.
Cglib代理,也叫作子類代理,它是在內(nèi)存中構(gòu)建一個(gè)子類對(duì)象從而實(shí)現(xiàn)對(duì)目標(biāo)對(duì)象功能的擴(kuò)展.
JDK的動(dòng)態(tài)代理有一個(gè)限制,就是使用動(dòng)態(tài)代理的對(duì)象必須實(shí)現(xiàn)一個(gè)或多個(gè)接口,如果想代理沒有實(shí)現(xiàn)接口的類,就可以使用Cglib實(shí)現(xiàn).Cglib是一個(gè)強(qiáng)大的高性能的代碼生成包,它可以在運(yùn)行期擴(kuò)展java類與實(shí)現(xiàn)java接口.它廣泛的被許多AOP的框架使用,例如Spring AOP和synaop,為他們提供方法的interception(攔截)Cglib包的底層是通過使用一個(gè)小而塊的字節(jié)碼處理框架ASM來轉(zhuǎn)換字節(jié)碼并生成新的類.不鼓勵(lì)直接使用ASM,因?yàn)樗竽惚仨殞?duì)JVM內(nèi)部結(jié)構(gòu)包括class文件的格式和指令集都很熟悉.
Cglib子類代理實(shí)現(xiàn)方法:
1.需要引入cglib的jar文件,但是Spring的核心包中已經(jīng)包括了Cglib功能,所以直接引入pring-core-3.2.5.jar即可.
2.引入功能包后,就可以在內(nèi)存中動(dòng)態(tài)構(gòu)建子類
3.代理的類不能為final,否則報(bào)錯(cuò)
4.目標(biāo)對(duì)象的方法如果為final/static,那么就不會(huì)被攔截,即不會(huì)執(zhí)行目標(biāo)對(duì)象額外的業(yè)務(wù)方法.
代碼示例:
目標(biāo)對(duì)象類:UserDao.java
/** * 目標(biāo)對(duì)象,沒有實(shí)現(xiàn)任何接口 */public class UserDao { public void save() { System.out.println("----已經(jīng)保存數(shù)據(jù)!----"); } }
Cglib代理工廠:ProxyFactory.java
/** * Cglib子類代理工廠 * 對(duì)UserDao在內(nèi)存中動(dòng)態(tài)構(gòu)建一個(gè)子類對(duì)象 */public class ProxyFactory implements MethodInterceptor{ //維護(hù)目標(biāo)對(duì)象 private Object target; public ProxyFactory(Object target) { this.target = target; } //給目標(biāo)對(duì)象創(chuàng)建一個(gè)代理對(duì)象 public Object getProxyInstance(){ //1.工具類 Enhancer en = new Enhancer(); //2.設(shè)置父類 en.setSuperclass(target.getClass()); //3.設(shè)置回調(diào)函數(shù) en.setCallback(this); //4.創(chuàng)建子類(代理對(duì)象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("開始事務(wù)..."); //執(zhí)行目標(biāo)對(duì)象的方法 Object returnValue = method.invoke(target, args); System.out.println("提交事務(wù)..."); return returnValue; } }
測(cè)試類:
/** * 測(cè)試類 */public class App { @Test public void test(){ //目標(biāo)對(duì)象 UserDao target = new UserDao(); //代理對(duì)象 UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance(); //執(zhí)行代理對(duì)象的方法 proxy.save(); } }
在Spring的AOP編程中:
如果加入容器的目標(biāo)對(duì)象有實(shí)現(xiàn)接口,用JDK代理
如果目標(biāo)對(duì)象沒有實(shí)現(xiàn)接口,用Cglib代理
相關(guān)推薦:java入門教程
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!

Outils d'IA chauds

Undress AI Tool
Images de déshabillage gratuites

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Article chaud

Outils chauds

Bloc-notes++7.3.1
éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Pour gérer correctement les transactions JDBC, vous devez d'abord désactiver le mode de validation automatique, puis effectuer plusieurs opérations, et enfin vous engager ou randonner en fonction des résultats; 1. Appelez Conn.SetAutoCommit (false) pour démarrer la transaction; 2. Exécuter plusieurs opérations SQL, telles que l'insertion et la mise à jour; 3. Appelez Conn.Commit () Si toutes les opérations sont réussies, et appelez Conn.Rollback () Si une exception se produit pour garantir la cohérence des données; Dans le même temps, les ressources TRY-With doivent être utilisées pour gérer les ressources, gérer correctement les exceptions et cl?turer les connexions pour éviter la fuite de connexion; De plus, il est recommandé d'utiliser des pools de connexion et de définir des points de sauvegarde pour réaliser un retour en arrière partiel, et de maintenir les transactions aussi courtes que possible pour améliorer les performances.

Utilisez des classes dans le package Java.Time pour remplacer les anciennes classes de date et de calendrier; 2. Obtenez la date et l'heure actuelles via LocalDate, LocalDateTime et Localtime; 3. Créez une date et une heure spécifiques en utilisant la méthode OF (); 4. Utilisez la méthode plus / moins pour augmenter et diminuer le temps; 5. Utilisez ZonedDateTime et ZoneID pour traiter le fuseau horaire; 6. Format et cha?nes de date d'analyse via DateTimeFormatter; 7. Utilisez instantanément pour être compatible avec les anciens types de dates si nécessaire; Le traitement des dattes dans le Java moderne devrait donner la priorité à l'utilisation de Java.timeapi, qui fournit clairement, immuable et linéaire

Pré-formancetartuptimemoryusage, quarkusandmicronautleadduetocompile-timeprocessingandgraalvsupport, withquarkusofperforming lightbetterine scénarios.

HTTP Log Middleware dans GO peut enregistrer les méthodes de demande, les chemins de requête, la propriété intellectuelle du client et le temps qui prend du temps. 1. Utilisez http.handlerfunc pour envelopper le processeur, 2. Enregistrez l'heure de début et l'heure de fin avant et après l'appel Suivant.Servehttp, 3. Obtenez le vrai client IP via R.RemoteAddr et X-Forwared-For Headers, 4. Utilisez le log.printf aux journaux de demande de sortie, 5. L'exemple de code complet a été vérifié pour s'exécuter et convient au démarrage d'un projet petit et moyen. Les suggestions d'extension incluent la capture des codes d'état, la prise en charge des journaux JSON et le suivi des ID de demande.

La collecte des ordures de Java (GC) est un mécanisme qui gère automatiquement la mémoire, ce qui réduit le risque de fuite de mémoire en récupérant des objets inaccessibles. 1. GC juge l'accessibilité de l'objet de l'objet racine (tel que les variables de pile, les threads actifs, les champs statiques, etc.), et les objets inaccessibles sont marqués comme des ordures. 2. Sur la base de l'algorithme de compensation de marque, marquez tous les objets accessibles et effacez des objets non marqués. 3. Adopter une stratégie de collecte générationnelle: la nouvelle génération (Eden, S0, S1) exécute fréquemment MinorGC; Les personnes agées fonctionnent moins, mais prend plus de temps pour effectuer MajorGC; Metaspace Stores Metadata de classe. 4. JVM fournit une variété de périphériques GC: SerialGC convient aux petites applications; Le parallelGC améliore le débit; CMS réduit

Le choix du bon type HTMLinput peut améliorer la précision des données, améliorer l'expérience utilisateur et améliorer la convivialité. 1. Sélectionnez les types d'entrée correspondants en fonction du type de données, tels que le texte, le courrier électronique, le tel, le numéro et la date, qui peuvent vérifier automatiquement la somme de la somme et l'adaptation au clavier; 2. Utilisez HTML5 pour ajouter de nouveaux types tels que l'URL, la couleur, la plage et la recherche, qui peuvent fournir une méthode d'interaction plus intuitive; 3. Utilisez l'espace réservé et les attributs requis pour améliorer l'efficacité et la précision du remplissage des formulaires, mais il convient de noter que l'espace réservé ne peut pas remplacer l'étiquette.

GradleisthebetterChoiceFormostNewProjectsDuetOtsSuperiorflexibility, Performance et ModerNtoolingSupport.1.gradle’sgroovy / kotlindslismoreConcis

Le report est utilisé pour effectuer des opérations spécifiées avant le retour de la fonction, telles que les ressources de nettoyage; Les paramètres sont évalués immédiatement lorsqu'ils sont reportés et les fonctions sont exécutées dans l'ordre de la dernière entrée (LIFO); 1. Plusieurs éleveurs sont exécutés dans l'ordre inverse des déclarations; 2. Communément utilisé pour le nettoyage sécurisé tel que la fermeture des fichiers; 3. La valeur de retour nommée peut être modifiée; 4. Il sera exécuté même si la panique se produit, adaptée à la récupération; 5. éviter l'abus de report dans les boucles pour éviter la fuite des ressources; Une utilisation correcte peut améliorer la sécurité et la lisibilité du code.
