Java-动态代理的两种实现

第一种:基本逻辑,代理类实现 InvocationHandler接口,代理类持有 实现类对象,提供创建代理类,在invoke代理方法执行时 通过反射执行实现类的具体方法,并在执行前后增加逻辑

  • 1.准备一个用于代理的接口方法
public interface ISpeaker{
       void speak(String c);
   }
  • 2.实现类
    public static class SpeakerA implements ISpeaker{
        @Override
        public void speak(String msg) {
            LogUtils.sysPrintln("SpeakerA-speak:%s",msg);
        }
    }
  • 3.代理类
public static class SpeakerProxy implements InvocationHandler{
       private Object delegate;//被代理的对象

       public SpeakerProxy(Object delegate) {
           this.delegate = delegate;
       }

       public Object bindProxy(){
           return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),delegate.getClass().getInterfaces(),this);
       }

       @Override
       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           LogUtils.sysPrintln("SpeakerProxy:进入代理,实际对象执行前1");
           //优化-捕获方法执行异常
          Object result = null;
          try {
              LogUtils.sysPrintln("SpeakerProxy:反射调用开始 2");
              result =  method.invoke(delegate,args);
              LogUtils.sysPrintln("SpeakerProxy:反射调用结束 3");
          }catch (Exception e){
          }
           LogUtils.sysPrintln("SpeakerProxy:结束代理 4");
           return result;
       }

   }
  • 代理使用
        SpeakerProxy speakerProxy = new SpeakerProxy(new SpeakerA());
        ISpeaker iSpeaker = (ISpeaker) speakerProxy.bindProxy();
        iSpeaker.speak("DynamicProxy call speak");
//        SpeakerProxy:进入代理,实际对象执行前1
//        SpeakerProxy:反射调用开始 2
//        SpeakerA-speak:DynamicProxy call speak
//        SpeakerProxy:反射调用结束 3
//        SpeakerProxy:结束代理 4

第二种:基于第一种的简化实现,快速实现代理指定方法。代理类 与被代理类 都实现 同一个 功能接口,代理类本身只做反射 调用真实对象的逻辑(感觉不容易说清楚。。。看实例吧)

  • 1.实现类
    public static class SpeakerB implements ISpeaker{
        @Override
        public void speak(String msg) {
            LogUtils.sysPrintln("SpeakerB-speak:%s",msg);
        }
    }
  • 2.代理类
public static class SpeakerPrxy2 implements ISpeaker{

        private Object delegate;

        public SpeakerPrxy2(Object delegate) {
            this.delegate = delegate;
        }

        @Override
        public void speak(String msg) {
            LogUtils.sysPrintln("SpeakerPrxy2:进入代理,实际对象执行前1");
            //优化-捕获方法执行异常
            try {
                LogUtils.sysPrintln("SpeakerPrxy2:反射调用开始 2");
                Class c = delegate.getClass();
                Method method = c.getDeclaredMethod("speak",String.class);
                if(Modifier.isPrivate(method.getModifiers())){
                    method.setAccessible(true);
                }
                method.invoke(delegate,msg);
                LogUtils.sysPrintln("SpeakerPrxy2:反射调用结束 3");
            }catch (Exception e){
            }
            LogUtils.sysPrintln("SpeakerPrxy2:结束代理 4");
        }
    }
  • 3.使用代理
        SpeakerPrxy2 speakerPrxy2 = new SpeakerPrxy2(new SpeakerB());
        speakerPrxy2.speak("SpeakerPrxy2 call speak");
//        SpeakerPrxy2:进入代理,实际对象执行前1
//        SpeakerPrxy2:反射调用开始 2
//        SpeakerB-speak:SpeakerPrxy2 call speak
//        SpeakerPrxy2:反射调用结束 3
//        SpeakerPrxy2:结束代理 4

这两种动态代理的方式,本质上没有特别大的区别。第二种是自己实现类代理类的创建。针对单个方法代理 速度比较快 风险更小。


END

你可能感兴趣的:(Java-动态代理的两种实现)