写在前面: 代理模式,字面上的意思就是代理某个人去做某件事。比如代办证件,可以找代办公司帮忙代理办证。
根据代理的创建时期,代理模式分为静态代理和动态代理。
代理模式的应用场景
当无法或不想直接引用某个对象或访问某个对象存在困难时,可以通过代理对象来间接访问。使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。
动态代理
在程序运行时,运用反射机制动态创建而成。字节码随用随创建,随用随加载。 Spring的AOP中就使用了动态代理对代码的增强。
应用案例: 文件服务对删除文件时增强。
实现如下:
1.抽象主题:
/**
* 抽象文件服务
*
* @Author JUNSHI
* @Create 2022-04-06 17:00
*/
public interface IFileService {
/**
* 删除文件
*/
void deleteFile(String fileId);
}
2.真实主题:
/**
* 对象存储上传文件
*
* @Author JUNSHI
* @Create 2022-04-07 14:43
*/
@Service
public class OssFileService implements IFileService {
@Override
public void deleteFile(String fileId) {
System.out.println("OSS删除文件:" + fileId);
}
}
代理一: SpringBoot整合Jdk的动态代理实现(基于接口类的动态代理)
/**
* JDK代理服务
* 基于接口类的动态代理
*
* @Author JUNSHI
* @Create 2022-04-07 14:45
*/
@Service("proxyService")
public class ProxyService implements InvocationHandler{
/**
* 需要代理的目标对象
*/
private Object target;
/**
* 作用:执行被代理对象的任何接口方法都会经过该方法
* 方法参数的含义
* @param proxy 代理对象的引用
* @param method 当前执行的方法
* @param args 当前执行方法所需的参数
* @return 和被代理对象方法有相同的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before执行~~~");
// 反射机制
Object invoke = method.invoke(target, args);
System.out.println("After执行~~~");
return invoke;
}
/**
* 获取代理对象
*/
public Object getProxy(Object targetObject){
// 赋于真实对象
this.target = targetObject;
// 实现接口的类进行代理,代理真实对象
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
}
}
代理二: SpringBoot整合Cglib的动态代理实现(基于子类的动态代理)
/**
* Cglib代理服务
* 基于子类的动态代理
*
* @Author JUNSHI
* @Create 2022-04-07 14:45
*/
@Service("cglibProxyService")
public class CglibProxyService implements MethodInterceptor {
/**
* 需要代理的真实对象
*/
private Object target;
/**
* 获取代理对象
*/
public Object getProxy(Object targetObject){
// 赋于真实对象
this.target = targetObject;
// 实现接口的类进行代理,代理真实对象
Enhancer enhancer = new Enhancer();
// 用于指定被代理对象的字节码
enhancer.setSuperclass(targetObject.getClass());
// 设置回调
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
/**
*
* 执行北地阿里对象的任何方法都会经过该方法
* @param proxy
* @param method
* @param args
* 以上三个参数和基于接口的动态代理中invoke方法的参数是一样的
* @param methodProxy :当前执行方法的代理对象
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("Cglib-Before执行~~~");
// 反射机制
Object invoke = method.invoke(target, args);
System.out.println("Cglib-After执行~~~");
return invoke;
}
}
测试用例:
@SpringBootTest
class SpringDesignModeApplicationTests {
@Autowired
private IFileService fileService;
@Autowired
private ProxyService proxyService;
@Autowired
private CglibProxyService cglibProxyService;
@Test
void testJDKProxyService() {
IFileService proxy =(IFileService) proxyService.getProxy(fileService);
// 真实对象删除文件
fileService.deleteFile("2");
System.out.println("================分隔符================");
// 代理对象删除文件
proxy.deleteFile("1");
}
@Test
void testCglibProxyService() {
IFileService proxy =(IFileService) cglibProxyService.getProxy(fileService);
// 真实对象删除文件
fileService.deleteFile("2");
System.out.println("================分隔符================");
// 代理对象删除文件
proxy.deleteFile("1");
}
}
1.JDK代理测试结果:

2. Cglib代理测试结果:
版权声明:本文为weixin_46146269原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。