找回密码
 立即注册
首页 业界区 业界 设计模式—结构型模式之代理模式

设计模式—结构型模式之代理模式

蔡如风 昨天 08:26
设计模式—结构型模式之代理模式

代理模式(Proxy Pattern) ,给某一个对象提供一个代理,并由代理对象控制对原对象的引用,对象结构型模式。
静态代理

比如我们有一个直播平台,提供了直播功能,但是如果不进行美颜,可能就比较冷清。所以美颜功能就是我们的增强,可以用静态代理来实现。
直播接口:
  1. /**
  2. * 直播接口
  3. */
  4. public interface LiveBroadCastInterface {
  5.     void liveBroadcast();
  6. }
复制代码
直播类:
  1. /**
  2. * 实现直播接口
  3. */
  4. public class SjdwzLiveBroadCast implements LiveBroadCastInterface{
  5.     @Override
  6.     public void liveBroadcast() {
  7.         System.out.println("我来直播了......");
  8.     }
  9. }
复制代码
如果没有美颜,可能就会比较冷清;所以我们可以提供一个静态代理,来为我们的直播进行增强。
要代理的功能类要和原类型实现相同的接口。
  1. public class SjdwzStaticProxy implements  LiveBroadCastInterface{
  2.    
  3.     private LiveBroadCastInterface liveBroadCastInterface;
  4.     public SjdwzStaticProxy(LiveBroadCastInterface liveBroadCastInterface) {
  5.         this.liveBroadCastInterface = liveBroadCastInterface;
  6.     }
  7.     @Override
  8.     public void liveBroadcast() {
  9.         System.out.println("这是代理的功能");
  10.         System.out.println("美颜--------");
  11.         System.out.println("=========原功能如下=========");
  12.         this.liveBroadCastInterface.liveBroadcast();
  13.     }
  14. }
复制代码
测试类如下:
  1. public class StaticSjdwzProxyTest {
  2.     public static void main(String[] args) {
  3.         SjdwzStaticProxy sjdwzStaticProxy = new SjdwzStaticProxy(new SjdwzLiveBroadCast());
  4.         sjdwzStaticProxy.liveBroadcast();
  5.     }
  6. }
复制代码
运行如下:
1.webp

jdk动态代理

还是上面的例子,可以使用JDK的动态代理来实现:
  1. /**
  2. * 实现InvocationHandler的作用是为了在本类实现增强方法,
  3. * @param <T> 要代理对象实现的接口
  4. */
  5. public class JdkLiveBroadCastProxy<T> implements InvocationHandler {
  6.     //被代理对象
  7.     private T target;
  8.     public JdkLiveBroadCastProxy(T target) {
  9.         this.target = target;
  10.     }
  11.     public static<T> T getProxy(T t){
  12.         /**
  13.          * ClassLoader loader, 当前被代理对象的类加载器
  14.          * Class<?>[] interfaces, 当前被代理对象所实现的所有接口
  15.          * InvocationHandler h,
  16.          *  当前被代理对象执行目标方法的时候我们使用h可以定义拦截增强方法
  17.          */
  18.         Object o = Proxy.newProxyInstance(
  19.                 t.getClass().getClassLoader(),
  20.                 t.getClass().getInterfaces(), //必须接口
  21.                 new JdkLiveBroadCastProxy(t));
  22.         return (T)o;
  23.     }
  24.     @Override
  25.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  26.         System.out.println("这是代理的一些功能======");
  27.         System.out.println("原本的功能===========");
  28.         //反射执行
  29.         Object invoke = method.invoke(this.target, args);
  30.         System.out.println("返回值:"+invoke);
  31.         return invoke;
  32.     }
  33. }
复制代码
测试类如下:
  1. public class JdkLiveBroadCastProxyTest {
  2.     public static void main(String[] args) {
  3.         LiveBroadCastInterface proxy = JdkLiveBroadCastProxy.getProxy(new SjdwzLiveBroadCast());
  4.         proxy.liveBroadcast();
  5.     }
  6. }
复制代码
运行结果如下:
2.webp

要求

JDK要求被代理对象必须有接口,因为必须有接口才能告诉代理有哪些方法。
cglib动态代理

我们发现,如果使用JDK的动态代理,必须实现接口。cglib动态代理是不需要实现接口的。
首先我们在项目的pom文件中引入依赖:
  1. <dependency>
  2.     <groupId>cglib</groupId>
  3.     cglib</artifactId>
  4.     <version>3.3.0</version>
  5. </dependency>
复制代码
cglib动态代理类如下:
  1. public class CglibProxy {
  2.     //为任意对象创建代理
  3.     public static<T> T createProxy(T t){
  4.         //1、创建一个增强器
  5.         Enhancer enhancer = new Enhancer();
  6.         //2、设置要增强哪个个类的功能。增强器为这个类动态创建一个子类
  7.         enhancer.setSuperclass(t.getClass());
  8.         //3、设置回调
  9.         enhancer.setCallback(new MethodInterceptor() {
  10.             @Override
  11.             public Object intercept(Object obj,
  12.                                     Method method,  //为了能获取到原方法的一些元数据信息
  13.                                     Object[] args,
  14.                                     MethodProxy proxy) throws Throwable {
  15.                 //编写增强的逻辑
  16.                 System.out.println("cglib的动态代理增强的功能===========");
  17.                 System.out.println("原功能===========");
  18.                 //目标方法进行执行
  19.                 Object invoke = proxy.invokeSuper(obj,args);
  20.                 return invoke;
  21.             }
  22.         });
  23.         Object o = enhancer.create();
  24.         return (T) o;
  25.     }
  26. }
复制代码
测试类如下:
  1. public class MyCglibProxyTest {
  2.     public static void main(String[] args) {
  3.         SjdwzLiveBroadCast proxy = CglibProxy.createProxy(new SjdwzLiveBroadCast());
  4.         proxy.liveBroadcast();
  5.     }
  6. }
复制代码
运行截图如下:
3.webp


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册