52 动态代理

动态代理

反射的应用:动态代理

代理设计模式 的原理:

使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象。

 

动态代理使用的场合:

        > 调式
>
> 远程方法调用

动态代理相比于静态代理的有点:

抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和统一的处理众多的方法。

 

静态代理:

特点:代理类和被代理类在编译期间,就确定下来了

interface ClothFactory{

   void productCloth();

}

class proxyClothFactory implements  ClothFactory{

   private ClothFactory factory;//用被代理类对象进行实例化

   public proxyClothFactory(ClothFactory factory){
       this.factory = factory;
  }


   @Override
   public void productCloth() {
       System.out.println("代理工厂做一些准备");

       factory.productCloth();

       System.out.println("代理工厂进行收尾");

  }
}

class nikeFactory implements ClothFactory{

   @Override
   public void productCloth() {
       System.out.println("nike工厂生产");
  }
}


public class StaticProxyTest {

   public static void main(String[] args) {
       //创建被代理类的对象
       nikeFactory nike = new nikeFactory();
       //创建代理类的对象
       proxyClothFactory proxyClothFactory = new proxyClothFactory(nike);

       proxyClothFactory.productCloth();
  }
}

 

要想实现动态代理,需要解决的问题?

问题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象

问题二:当通过代理类的对象调用方法a时,如何动态的去调用被代理类中的同名方法a

interface Human{

   String getBelief();
   void eat(String food);
}

class SuperMan implements Human{

   @Override
   public String getBelief() {
       return "要有信仰";
  }

   @Override
   public void eat(String food) {
       System.out.println("我要吃" + food);
  }
}


class proxyFactory{
   //调用此方法,返回一个代理类的对象,解决问题一
   public static Object getProxyInstance(Object obj){//obj:被代理类的对象

       MyInvocation myInvocation = new MyInvocation();

       myInvocation.band(obj);

     return  Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),myInvocation);

  }
}

class MyInvocation implements InvocationHandler {

   private Object obj;//需要使用被代理类的对象进行赋值

   public void band(Object obj){
       this.obj = obj;
  }

   //当我们通过代理类的对象,调用方法a时,就会自动调用如下的方法:invoke()
   //将被代理类要执行的方法a的功能就声明在invoke()中
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       //method:即为代理类对象调用的方法,此方法也就作为被代理类对象要调用的方法
       //obj:被代理类的对象
       Object returnValue = method.invoke(obj, args);
       //上述方法的返回值就作为当前类中的invoke()的返回值
       return returnValue;
  }
}




public class ProxyTest {
   public static void main(String[] args) {
       SuperMan superMan = new SuperMan();
       //proxyInstance:代理类的对象
       Human proxyInstance = (Human) proxyFactory.getProxyInstance(superMan);
       //当通过代理类对象调用方法时,会自动的调用被代理类的同名方法
       proxyInstance.getBelief();
       proxyInstance.eat("锅贴");

  }

}

 

posted @   flypiggg  阅读(227)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示