В некоторых проектах Java MapperScannerConfigurer используется при интеграции mybatis и Spring. Этот класс автоматически генерирует динамические прокси-классы на основе интерфейса через обратный прокси.
В связи с этим в данной статье кратко анализируется динамический прокси Java.
В этой статье динамический прокси используется для имитации перехватчика, обрабатывающего транзакции.
интерфейс:
общедоступный интерфейс UserService {общественный недействительный addUser ();Класс реализации:
общественный класс UserServiceImpl реализует UserService { public void addUser() { System.out.println("добавить пользователя" } public void removeUser() { System.out.println("удалить пользователя" } public void searchUser()); System.out.println("найти пользователя" }};Существует два способа реализации динамического прокси-сервера Java.
1. Динамический прокси, входящий в состав jdk
Чтобы использовать динамический прокси-сервер, поставляемый с jdk, вам необходимо понять интерфейс IndictionHandler и класс Proxy. Оба они находятся в пакете java.lang.reflect.
Введение в InvoctionHandler:
InvoctionHandler — это интерфейс, реализованный обработчиком вызова экземпляра прокси.
С каждым экземпляром прокси-сервера связан InvoctionHandler. При вызове метода в экземпляре прокси-сервера этот метод вызывает метод вызова InvoctionHandler.
Введение в прокси:
Proxy предоставляет статические методы для создания динамических прокси-классов и экземпляров.
Пример (имитация обработки транзакций AOP):
общедоступный класс TransactionInterceptor реализует InlocationHandler { цель частного объекта; public void setTarget (цель объекта) { this.target = цель; } @Override public Object вызова (прокси-сервер объекта, метод метода, Object [] args) бросает Throwable { System.out.println («начать транзакцию»); System.out.println («завершить транзакцию»); вернуть ноль }};Тестовый код:
общественный класс TestDynamicProxy { @Test public void testJDK () { TransactionInterceptor transactionInterceptor = новый UserService userService = новый UserServiceImpl (); .getClassLoader(), userService.getClass().getInterfaces(), транзакцияInterceptor); userServiceProxy.addUser() }};Результаты испытаний:
начать транзакциюдобавить пользователязавершить транзакцию
Очевидно, что когда мы вызываем метод через прокси-класс userServiceProxy, транзакция будет открываться и закрываться до и после вызова метода.
2. Сторонняя библиотека cglib.
CGLIB — это мощная, высокопроизводительная и высококачественная библиотека генерации кода для расширения классов Java и реализации интерфейсов Java во время выполнения.
Самая большая разница между ним и динамическим прокси JDK:
Динамический прокси JDK предназначен для интерфейсов, а cglib реализует прокси для классов. Принцип cglib заключается в создании подкласса для указанного целевого класса и перезаписи методов для достижения улучшения. Однако, поскольку используется наследование, окончательный класс не может быть изменен. прокси.
Пример кода выглядит следующим образом:
публичный класс UserServiceCallBack реализует 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("завершить транзакцию cglib"); return null }};Тестовый код:
общественный класс TestDynamicProxy { @Test public void testCGLIB() { Enhancer Enhancer = new Enhancer(); Enhancer.setCallback(new UserServiceCallBack()); ; прокси.добавитьПользователя() }};Результаты испытаний:
начало транзакции cglibadd userend транзакция cglib
Заинтересованные читатели могут протестировать примеры из этой статьи, и я уверен, что они многое получат.