Java动态代理

主要是实现动态增强接口的功能
具体实现:

  1. 写一个接口,接口中封装了客户端需要的操作。
  2. 写一个委托类实现该接口
  3. 写一个代理类实现InvocationHandler接口,这个类中存在委托类的引用
  4. 客户端利用Proxy类的静态方法(反射技术),让接口关联代理实现类的对象,利用接口来调用方法,实际通过代理来访问委托类的方法。

静态代理

  • 写一个接口A,定义一些功能
  • 写一个类B,实现接口
  • 写一个类C,实现接口,并且C的内部有一个B实例,构造方法中也需要传入一个B对象b,重写接口方法时实际上是调用b对象的对应方法,但是此时可以添加一些其他的操作,相当于加强了类。
  • 图示
    图片说明
  • 代码
    // 静态代理,定义了一个代理类并且内部包含接口的一个实现类,代理类再实现接口,
    // 并且通过内部的类实例调用方法,本身只用于加强方法
    public class SimpleStaticProxyDemo {
        static interface IService {
            public void sayHello();
        }
    
        static class RealService implements IService {
            @Override
            public void sayHello() {
                System.out.println("你好呀!!");
            }
        }
    
        static class TraceProxy implements IService {
            private IService realService;
    
            public TraceProxy(IService realService) {
                this.realService = realService;
            }
    
            @Override
            public void sayHello() {
                System.out.println("进入sayHello方法");
                realService.sayHello();
                System.out.println("退出sayHello方法");
            }
        }
    
        public static void main(String[] args) {
            IService realService = new RealService();
            IService proxyService = new TraceProxy(realService);
            proxyService.sayHello();
        }
    }
    
    

动态代理

  • JDK动态代理

    • 代码
      import java.lang.reflect.*;
      
      public class SimpleJDKDynamicProxyDemo {
          static interface IService {
              public void sayHello();
          }
      
          static class RealService implements IService {
              @Override
              public void sayHello() {
                  System.out.println("你好呀!!");
              }
          }
      
          static class SimpleInvocationHandler implements InvocationHandler {
              private Object realObject;
      
              public SimpleInvocationHandler(Object realObject) {
                  this.realObject = realObject;
              }
      
              @Override
              public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                  System.out.println("进入" + method.getName() + "方法");
                  // 调用realObject对象的method方法,参数是args
                  Object result = method.invoke(realObject, args);
                  System.out.println("离开" + method.getName() + "方法");
                  return result;
              }
          }
      
          public static void main(String[] args) throws Exception {
              IService realService = new RealService();
              // 通过Proxy.getProxyClass创建代理类定义,类定义会被缓存
              Class proxyClass = Proxy.getProxyClass(IService.class.getClassLoader(), new Class<?>[]{IService.class});
              // 获取代理类的构造方法,构造方法中会有一个InvocationHandler类型的参数
              Constructor constructor = proxyClass.getConstructor(new Class[]{InvocationHandler.class});
              // 创建InvocationHandler和IService对象
              InvocationHandler handler = new SimpleInvocationHandler(realService);
              IService proxyService = (IService) constructor.newInstance(handler);
              proxyService.sayHello();
          }
      }
      
    • 本质上来看Proxy.getProxyClass会动态生成一个代理类,h是一个InvocationHandler类实例
      final class $Proxy0 extends Proxy implements SimpleJDKDynamicProxyDemo.IService {
          private static Method m1;
          private static Method m3;
          private static Method m2;
          private static Method m0;
      
          public $Proxy0(InvocationHandler paramInvocationHandler) {
              super(paramInvocationHandler);
          }
      
          public final boolean equals(Object paramObject) {
              return ((Boolean) h.invoke(this, m1, new Object[]{paramObject})).booleanValue();
          }
      
          public final void sayHello() {
              h.invoke(this, m3, null);
          }
      
          public final String toString() {
              return (String) h.invoke(this, m2, null);
          }
      
          public final int hashCode() {
              return ((Integer) h.invoke(this, m0, null)).intValue();
          }
      
          static {
              m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
              m3 = Class.forName("edu.hut.proxy.SimpleJDKDynamicProxyDemo$IService").getMethod("sayHello", new Class[0]);
              m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
              m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
          }
      }
      
  • 作用

    • 可以实现一种方法模板,只需要传入接口的class和一个实现了接口的类对象,就可以增强对应的方法(比如打印日志)
      • 代码
        import java.lang.reflect.*;
        
        public class GeneralProxyDemo {
            static interface IServiceA {
                public void sayHello();
            }
        
            static class ServiceAImpl implements IServiceA {
        
                @Override
                public void sayHello() {
                    System.out.println("你好呀!!");
                }
            }
        
            static interface IServiceB {
                public void fly();
            }
        
            static class ServiceBImpl implements IServiceB {
        
                @Override
                public void fly() {
                    System.out.println("正在飞翔!!");
                }
            }
        
            static class SimpleInvocationHandler implements InvocationHandler {
                private Object realObj;
        
                public SimpleInvocationHandler(Object realObj) {
                    this.realObj = realObj;
                }
        
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("进入 " + realObj.getClass().getSimpleName() + "类的" + method.getName() + "方法");
                    Object result = method.invoke(realObj, args);
                    System.out.println("退出 " + realObj.getClass().getSimpleName() + "类的" + method.getName() + "方法");
                    return result;
                }
            }
        
            private static <T> T getProxy(Class<T> intf, T realObj) {
                return (T) Proxy.newProxyInstance(intf.getClassLoader(), new Class<?>[] { intf }, new SimpleInvocationHandler(realObj));
            }
        
            public static void main(String[] args) throws Exception {
                IServiceA a = new ServiceAImpl();
                IServiceA aProxy = getProxy(IServiceA.class, a);
                aProxy.sayHello();
        
                System.out.println("\n--------------分界线--------------\n");
        
                IServiceB b = new ServiceBImpl();
                IServiceB bProxy = getProxy(IServiceB.class, b);
                bProxy.fly();
            }
        }
        
        // 运行结果
        进入 ServiceAImpl类的sayHello方法
        你好呀!!
        退出 ServiceAImpl类的sayHello方法
        
        --------------分界线--------------
        
        进入 ServiceBImpl类的fly方法
        正在飞翔!!
        退出 ServiceBImpl类的fly方法
        
  • cglib动态代理

    • 作用:可以代理类(JDK代理无法实现)
    • 代码
      public class SimpleCGLibDemo {
          static class RealService {
              public void sayHello() {
                  System.out.println("hello");
              }
          }
      
          static class SimpleInterceptor implements MethodInterceptor {
      
              @Override
              public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                  System.out.println("entering " + method.getName());
                  Object result = proxy.invokeSuper(object, args);
                  System.out.println("leaving " + method.getName());
                  return result;
              }
          }
      
          @SuppressWarnings("unchecked")
          private static <T> T getProxy(Class<T> cls) {
              Enhancer enhancer = new Enhancer();
              enhancer.setSuperclass(cls);
              enhancer.setCallback(new SimpleInterceptor());
              return (T) enhancer.create();
          }
      
          public static void main(String[] args) throws Exception {
              RealService proxyService = getProxy(RealService.class);
              proxyService.sayHello();
          }
      }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值