Dans certains projets Java, MapperScannerConfigurer est utilisé dans l'intégration de mybatis et spring. Cette classe génère automatiquement des classes proxy dynamiques basées sur l'interface via un proxy inverse.
Compte tenu de cela, cet article analyse brièvement le proxy dynamique de Java.
Cet article utilise un proxy dynamique pour simuler un intercepteur qui gère les transactions.
interface:
interface publique UserService { public void addUser(); public void removeUser(); public void searchUser();}Classe d'implémentation :
public class UserServiceImpl implémente UserService { public void addUser() { System.out.println("ajouter un utilisateur"); } public void removeUser() { System.out.println("remove user"); System.out.println("utilisateur de recherche"); }}Il existe deux façons d'implémenter le proxy dynamique Java
1. Le proxy dynamique fourni avec jdk
Pour utiliser le proxy dynamique fourni avec jdk, vous devez comprendre l'interface InvocationHandler et la classe Proxy. Ils se trouvent tous deux sous le package java.lang.reflect.
Introduction au gestionnaire d'appels :
InvocationHandler est l'interface implémentée par le gestionnaire d'appel de l'instance proxy.
Chaque instance de proxy est associée à un InvocationHandler. Lors de l’appel d’une méthode sur une instance proxy, cette méthode appelle la méthode d’invocation de InvocationHandler.
Présentation du proxy :
Proxy fournit des méthodes statiques pour créer des classes et des instances de proxy dynamiques.
Exemple (simulation du traitement des transactions AOP) :
public class TransactionInterceptor implémente InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } @Override public Object Invocation (Object proxy, Method method, Object[] args) throws Throwable { System.out.println ("démarrer la transaction"); méthode.invoke(target, args); System.out.println("fin de la transaction");Code d'essai :
public class TestDynamicProxy { @Test public void testJDK() { TransactionInterceptor transactionInterceptor = new TransactionInterceptor(); UserService userService = new UserServiceImpl(); .getClassLoader(), userService.getClass().getInterfaces(), transactionInterceptor); userServiceProxy.addUser();Résultats des tests :
démarrer la transactionajouter un utilisateurfin la transaction
Évidemment, lorsque nous effectuons un appel de méthode via la classe proxy userServiceProxy, la transaction sera ouverte et fermée avant et après l'appel de méthode.
2. Bibliothèque tierce cglib
CGLIB est une bibliothèque de génération de code puissante, hautes performances et de haute qualité permettant d'étendre les classes Java et d'implémenter des interfaces Java au moment de l'exécution.
La plus grande différence entre celui-ci et le proxy dynamique du JDK est :
Le proxy dynamique JDK est destiné aux interfaces, tandis que cglib implémente un proxy pour les classes. Le principe de cglib est de générer une sous-classe pour la classe cible spécifiée et d'écraser les méthodes pour obtenir une amélioration. Cependant, comme l'héritage est utilisé, final ne peut pas être la classe modifiée. mandaté.
L'exemple de code est le suivant :
public class UserServiceCallBack implémente MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("start Transaction by cglib"); ); System.out.println("fin de la transaction par cglib"); return null }}Code d'essai :
public class TestDynamicProxy { @Test public void testCGLIB() { Enhancer Enhancer = new Enhancer(); Enhancer.setSuperclass(UserServiceImpl.class); Enhancer.setCallback(new UserServiceCallBack()); ; proxy.addUser(); }}Résultats des tests :
démarrer la transaction par cglibadd userend Transaction par cglib
Les lecteurs intéressés peuvent tester les exemples de cet article et je pense qu’ils y gagneront beaucoup.