一、代理模式介绍
1、什么是代理模式?
代理模式是一种结构型设计模式,它允许为其他对象提供一个替代品或占位符,以控制对这个对象的访问。
2、代理模式的角色构成
- 抽象主题(Subject):定义了真实主题和代理主题的共同接口,这样代理类可以通过实现该接口来代理真实主题。
- 真实主题(Real Subject):定义了代理所代表的真实对象。
- 代理(Proxy):持有对真实主题的引用,并实现了与真实主题一样的接口,客户端通过代理来访问真实主题,同时可以在访问真实主题前后进行一些额外操作。
3、代理模式的作用
代理模式的主要目的是控制对对象的访问,可以实现一些额外的功能,比如延迟加载、访问控制、日志记录、性能监控等。代理模式在实际开发中有着广泛的应用,比如远程代理、虚拟代理、保护代理等。总的来说,代理模式提供了一种灵活的方式来控制对对象的访问,并且可以在不改变原始对象的情况下实现一些额外的功能。
二、静态代理模式实例Static Proxy
1、Shopping接口
package com.xu.demo.proxyPattern;
//接口
public interface Shopping {
void buy();
}
2、真实类RealShopping
package com.xu.demo.proxyPattern;
//真实类
public class RealShopping implements Shopping {
@Override
public void buy() {
System.out.println("购买商品");
}
}
3、静态代理类ShoppingProxy
package com.xu.demo.proxyPattern;
//代理类
public class ShoppingProxy implements Shopping {
private RealShopping realShopping;
public ShoppingProxy(RealShopping realShopping) {
this.realShopping = realShopping;
}
@Override
public void buy() {
System.out.println("开始记录日志");
realShopping.buy();
System.out.println("记录日志完成");
}
}
4、StaticProxy类测试
package com.xu.demo.proxyPattern;
/**
* 代理类代理接口的实现类调用接口方法
*/
public class StaticProxy {
public static void main(String[] args) {
RealShopping realShopping = new RealShopping();
ShoppingProxy shoppingProxy = new ShoppingProxy(realShopping);
shoppingProxy.buy();
}
}
运行结果:
二、Java动态代理
动态代理是在运行时动态生成代理类,不需要手动编写代理类。Java种的动态代理主要是使用java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler接口实现。
其中最主要的就是Proxy.newProxyInstance方法,它是用于创建动态代理对象的静态方法。它接受三个参数:
- ClassLoader:用于加载动态代理类的类加载器。
- interfaces:要代理的接口数组。
- InvocationHandler:实现了InvocationHandler接口的对象,用于处理代理对象的方法调用。
1、ShoppingInvocationHandler动态代理处理类
package com.xu.demo.proxyPattern;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
// 动态代理处理器
public class ShoppingInvocationHandler implements InvocationHandler {
private Object target;
public ShoppingInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始记录日志");
Object result = method.invoke(target, args);
System.out.println("记录日志完成");
return result;
}
}
2、动态代理类DynamicShoppingProxy
package com.xu.demo.proxyPattern;
import java.lang.reflect.Proxy;
// 动态代理类
public class DynamicShoppingProxy {
public static Shopping createProxy(RealShopping realShopping) {
return (Shopping) Proxy.newProxyInstance(
realShopping.getClass().getClassLoader(),
realShopping.getClass().getInterfaces(),
new ShoppingInvocationHandler(realShopping));
}
}
3、JDK代理测试类JavaDynamicProxy
运行:
三、CGLIB动态代理
CGLIB是一个强大的,高性能的代码生成类库,它可以在运行时扩展Java类。CGLIB代理不要求目标对象实现接口,它通过继承目标类生成代理类。
1、引入CGLIB依赖包,如果你是Spring项目的话Spring框架已经自带了CGLIB动态代理需要的依赖包
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
2、 ShoppingMethodInterceptorCGLIB代理处理器
package com.xu.demo.proxyPattern;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
// CGLIB代理处理器
public class ShoppingMethodInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
System.out.println("开始记录日志");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("记录日志完成");
return result;
}
}
3、CGLIB代理类CglibShoppingProxy
package com.xu.demo.proxyPattern;
import org.springframework.cglib.proxy.Enhancer;
// CGLIB代理类
public class CglibShoppingProxy {
public static Shopping createProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealShopping.class);
enhancer.setCallback(new ShoppingMethodInterceptor());
return (Shopping) enhancer.create();
}
}
4、CGLIB动态代理测试类CglibDynamicProxy
package com.xu.demo.proxyPattern;
/**
* CGLIB动态代理测试类
*/
public class CglibDynamicProxy {
public static void main(String[] args) {
Shopping cglibProxy = CglibShoppingProxy.createProxy();
cglibProxy.buy();
}
}
运行结果: