代理(Proxy)🔥#
约 344 个字 25 行代码 1 张图片 预计阅读时间 8 分钟
意图#
为目标对象提供一种代理以控制对这个对象的访问。
结构#
服务接口(Service Interface)
声明了服务接口。代理必须遵循该接口才能伪装成服务对象。服务(Service)
类提供了一些实用的业务逻辑。代理(Proxy)
类包含一个指向服务对象的引用成员变量。代理完成其任务(例如延迟初始化、记录日志、访问控制和缓存等)后会将请求传递给服务对象。下,代理会对其服务对象的整个生命周期进行管理。客户端(Client)
能通过同一接口与服务或代理进行交互,所以你可在一切需要服务对象的代码中使用代理。
静态代理#
代码实现#
服务接口:
Java
package com.luguosong.structural.proxy.static_proxy;
/**
* @author luguosong
*/
public interface UserService {
void addUser();
void editUser();
void deleteUser();
}
服务具体实现:
Java
package com.luguosong.structural.proxy.static_proxy;
/**
* @author luguosong
*/
public class UserServiceImpl implements UserService{
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void editUser() {
System.out.println("修改用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
静态代理:
Java
package com.luguosong.structural.proxy.static_proxy;
/**
* @author luguosong
*/
public class UserServiceProxy implements UserService{
private UserService userService;
public UserServiceProxy(UserService userService) {
this.userService = userService;
}
@Override
public void addUser() {
System.out.println("前置增强");
userService.addUser();
System.out.println("后置增强");
}
@Override
public void editUser() {
System.out.println("前置增强");
userService.editUser();
System.out.println("后置增强");
}
@Override
public void deleteUser() {
System.out.println("前置增强");
userService.deleteUser();
System.out.println("后置增强");
}
}
测试代码:
Java
package com.luguosong.structural.proxy.static_proxy;
/**
* @author luguosong
*/
public class Test {
public static void main(String[] args) {
UserService proxy = new UserServiceProxy(new UserServiceImpl());
proxy.addUser();
}
}
静态代理存在的问题#
- 需要为所有想要被代理的
服务(Service)
编写代理类(Proxy)
,会导致代理类爆炸式增多。
动态代理#
JDK动态代理#
服务接口:
Java
package com.luguosong.structural.proxy.dynamic_proxy_jdk;
/**
* @author luguosong
*/
public interface UserService {
void addUser();
void editUser();
void deleteUser();
}
服务具体实现:
Java
package com.luguosong.structural.proxy.dynamic_proxy_jdk;
/**
* @author luguosong
*/
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void editUser() {
System.out.println("修改用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
在测试类中直接生成代理对象:
Java
package com.luguosong.structural.proxy.dynamic_proxy_jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author luguosong
*/
public class Test {
public static void main(String[] args) {
UserService service = new UserServiceImpl();
UserService serviceProxy = (UserService) Proxy.newProxyInstance(service.getClass().getClassLoader(),
service.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("前置增强");
Object ret = method.invoke(service, args);
System.out.println("后置增强");
return ret;
}
});
serviceProxy.addUser();
}
}
cglib动态代理#
使用cglib动态代理需要导入相关依赖:
XML
<dependencies>
<!--❌这个依赖已经不维护了,JDK17调用会报错-->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<!--可以使用Spring内部的cglib实现,支持JDK17-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.8</version>
</dependency>
</dependencies>
没有接口的服务类:
Java
package com.luguosong.structural.proxy.dynamic_proxy_cglib;
/**
* @author luguosong
*/
public class UserServiceImpl {
public void addUser() {
System.out.println("添加用户");
}
public void editUser() {
System.out.println("修改用户");
}
public void deleteUser() {
System.out.println("删除用户");
}
}
在测试类中动态创建代理对象:
Java
package com.luguosong.structural.proxy.dynamic_proxy_cglib;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
/**
* @author luguosong
*/
public class Test {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserServiceImpl.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> {
System.out.println("前置增强");
Object ret = proxy.invokeSuper(obj, args1);
System.out.println("后置增强");
return ret;
});
UserServiceImpl userService = (UserServiceImpl)enhancer.create();
userService.addUser();
}
}