В Spring AOP (Aspect-Oriented Programming — аспектно-ориентированное программирование) прокси (proxy) — это объект, который создается фреймворком для реализации аспектов (aspects) вокруг целевого объекта (target object). Прокси перехватывает вызовы методов целевого объекта и добавляет дополнительную логику, такую как логирование, транзакции, безопасность и т.д., без изменения исходного кода целевого объекта.
Spring AOP использует два типа прокси:
Если целевой объект реализует интерфейс, Spring создает динамический прокси с использованием стандартного механизма JDK. Этот прокси реализует тот же интерфейс, что и целевой объект, и перехватывает вызовы методов.
Пример:
public interface UserService {
void saveUser(User user);
}
public class UserServiceImpl implements UserService {
@Override
public void saveUser(User user) {
// Логика сохранения пользователя
}
}
// Прокси, созданный Spring AOP
UserService proxy = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
new Class<?>[] { UserService.class },
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Логика до вызова метода
System.out.println("Before method: " + method.getName());
// Вызов целевого метода
Object result = method.invoke(targetObject, args);
// Логика после вызова метода
System.out.println("After method: " + method.getName());
return result;
}
}
);
Если целевой объект не реализует интерфейс, Spring использует библиотеку CGLIB для создания прокси. CGLIB создает подкласс целевого объекта и переопределяет его методы.
Пример:
public class UserService {
public void saveUser(User user) {
// Логика сохранения пользователя
}
}
// Прокси, созданный Spring AOP с использованием CGLIB
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// Логика до вызова метода
System.out.println("Before method: " + method.getName());
// Вызов целевого метода
Object result = proxy.invokeSuper(obj, args);
// Логика после вызова метода
System.out.println("After method: " + method.getName());
return result;
}
});
UserService proxy = (UserService) enhancer.create();
Прокси в Spring AOP — это мощный механизм для добавления дополнительной логики вокруг методов целевого объекта. Он позволяет реализовать аспектно-ориентированное программирование, разделяя бизнес-логику и кросс-резающие задачи. Spring использует JDK Dynamic Proxy для интерфейсов и CGLIB Proxy для классов, что делает его гибким и удобным инструментом для разработки.