java中的代理

24 阅读2分钟

定义

  • 是一种设计模式,提供对目标对象另外的访问方式

好处

  1. 目标对象可以间接访问
  2. 可以在目标对象实现的基础上,增强额外的功能,即扩展目标对象的功能
  3. 不改变原有代码的前提下,可以通过代理来扩展

分类

  1. 静态代理

    1. 示例(接口实现)

      通过让目标类和代理类实现同一个接口来进行关联目标类和代理类,代理类可以有自己的扩展方法

    2. 例一:(海外代购)
       // 接口
       public interface ByClothes {
           void clothes(String size);
       }
      
       // 目标类
       public class ClothesFactory implements ByClothes {
           @Override
           public void clothes(String size) {
               System.out.println("为您制作了" + size + "码的衣服");
           }
       }
      
       // 代理类
       public class ClothesProxy implements ByClothes {
       ​
           // 目标对象
           public ClothesFactory clothesFactory;
       ​
           public ClothesProxy(ClothesFactory clothesFactory) {
               // 保存目标对象
               this.clothesFactory = clothesFactory;
           }
       ​
           @Override
           public void clothes(String size) {
               // 额外的功能
               frontService();
               // 调用目标对象的方法
               clothesFactory.clothes(size);
       ​
               // 额外的功能
               endService();
           }
       ​
           public void frontService() {
               System.out.println("根据您的需求进行产品研发");
           }
       ​
           public void endService() {
               System.out.println("产品交付, 祝您使用愉快");
           }
       }
      
       // 测试类
       public class Test {
           public static void main(String[] args) {
               ClothesFactory clothesFactory = new ClothesFactory();
               ClothesProxy clothesProxy = new ClothesProxy(clothesFactory);
               clothesProxy.clothes("XL");
           }
       }
      

      通过代理类里面创建并调用目标类对象的方法来实现代理

       //最终输出
       根据您的需求进行产品研发
       工厂为您制作了XL码的衣服
       产品交付, 祝您使用愉快
      
  2. 动态代理

    1. jdk动态代理(接口)
      1. 示例2(代理多个品类)

         public interface ByShoot {
             void shoot(String size);
         }
        
         public class ShootFactory implements ByShoot {
             @Override
             public void shoot(String size) {
                 System.out.println("工厂为您制作了" + size + "码的鞋子");
             }
         }
        
         ​
         import java.lang.reflect.InvocationHandler;
         import java.lang.reflect.Method;
         import java.lang.reflect.Proxy;
         ​
         ​
         // 代理工厂类
         public class Company implements InvocationHandler {
             // 目标对象
             private Object factory;
         ​
             public Object getFactory() {
                 return factory;
             }
         ​
             public void setFactory(Object factory) {
                 this.factory = factory;
             }
         ​
             @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                 // 额外的操作
                 frontService();
                 // 调用目标对象的方法
                 Object obj = method.invoke(factory, args);
                 // 额外的操作
                 endService();
                 return obj;
             }
         ​
             // 获取代购员对象
             public Object getProxyInstance() {
                 return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
             }
         ​
             public void frontService() {
                 System.out.println("根据您的需求进行产品研发");
             }
         ​
             public void endService() {
                 System.out.println("产品交付, 祝您使用愉快");
             }
         }
        

        通过setFactory设置不同的工厂就可以获得不同的代理对象,从而实现动态代理

        // 测试类
        public class Test {
            public static void main(String[] args) {
                // 工厂实例
                ClothesFactory clothesFactory = new ClothesFactory();
                ShootFactory shootFactory = new ShootFactory();
                // 代购公司实例
                Company company = new Company();
                // 代购公司设置代购工厂
                company.setFactory(clothesFactory);
                // 获取代理对象
                ByClothes byClothes = (ByClothes) company.getProxyInstance();
                byClothes.clothes("XXL");
                // 代购公司设置代购工厂
                company.setFactory(shootFactory);
                // 获得代购对象
                ByShoot byShoot = (ByShoot) company.getProxyInstance();
                byShoot.shoot("41.5");
            }
        }
        
    2. CGLIB代理(继承)