zoukankan      html  css  js  c++  java
  • Java动态代理

    Java动态代理

    什么是动态代理?

    1、A接口有C方法,类B实现A接口,原本应该是执行B类中的C方法,可现在不这样做。

    2、现在声明产生B类的代理类‘B’,由它来冒充B类的“兄弟”并“实现”A接口。

    3、对外界来说‘B’应该也有C方法,可当真正的调用它时,它会执行与它关联InvocationHandler的invoke()方法,在这个方法里面你可以做很多事情。

    动态代理:

    代理模式是常用的java设计模式,它的特征是:

    》代理类与委托类有同样的接口

    》代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及时候处理消息等

    》代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联。

    》代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

    JDK动态代理中包含一个类和一个接口:
    InvocationHandler接口:
    public interface InvactionHandler{
            
          public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;  
    
    }
    参数说明:
    Object proxy:指被代理的对象
    Method method:要调用的方法
    Object[] args:方法调用时所需要的参数
    

      

    Proxy类:
    Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供如下操作的方法:
    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
    参数说明:
    ClassLoader loader:类加载器
    Class<?>[] interfaces:得到全部的接口
    InvocationHandler h:得到InvocationHandler接口的子类实例
    

      

    实例:

    public interface Dinner {
        public void haveDinner();
    }
    
    //被代理类
    public class MyDinner implements  Dinner{
        @Override
        public void haveDinner() {
            System.out.println("妈妈做饭真好吃");
        }
    }
    
    //代理类
    public class MyDinnerProxy implements InvocationHandler {
        private Object obj;
        //绑定被代理类对象,返回代理类对象
        public Object bind(Object obj){
            this.obj = obj;
            return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
        }
        private void before(){
            System.out.println("吃饭前洗手");
        }
        private void after(){
            System.out.println("吃饭后刷碗");
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            after();
            Object retrunVal = method.invoke(obj,args);
            before();
            return retrunVal;
        }
    }
    
    //测试类
        public static void main(String[] args){
    
            Dinner hd = new MyDinner();//可以调用被代理类重写的方法
            MyDinnerProxy mdp = new MyDinnerProxy();创建一个这个类的对象
            //返回一个代理类对象,向上转型,调用重写的方法,也就是invoke()方法
            hd = (Dinner) mdp.bind(hd);
            hd.haveDinner();
        }
    

      

  • 相关阅读:
    xss攻击和csrf攻击的定义及区别
    php中Redis的扩展
    MySQL事务特性
    PHP的设计模式
    http协议
    sql语句的优化
    mysql存储引擎
    laravel框架安装Curl扩展
    laravel框架中安装 elasticsearch 包
    docker容器配置nginx负载均衡 -----加权
  • 原文地址:https://www.cnblogs.com/yangHS/p/10735445.html
Copyright © 2011-2022 走看看