• Java反射及注解学习- 反射的使用


    代理模式基本概念:
    1.代理模式的作用:为其他对象提供一种以控制对方的访问
    在某种情况下,一个客户不想或者不能直接引用另一个对象,代理可以在客户端和目标对象之间起到中介的作用
    代理的角色:
    (1)抽象角色:声明真实对象和代理对象的共同接口(比如租房,抽象角色就是把租房这件事给抽象成一个接口)
    (2)代理角色:代理对象内部含有真实对象的引用,从而可以操纵真实的对象,同时代理对象提供与真实对象相同的接口,以便在任何时候都能代替真实对象。代理对象可以在执行真实对象操作时附加其他的操作(比如,租房时,中介收中介费),相对于真实对象进行封装。
    (3)真实角色:代理对象所代理的真实角色,是我们要引用的对象

    2.JDK动态代理
    JDK动态代理可以为所有接口的实现类提供代理
    动态代理开发步骤:
    (1)创建一个实现接口InvocationHandler的类,它必须实现invoke方法
    (2)创建被代理对象的类和接口
    (3)通过Proxy.newProxyInstance()来创建代理类
    (4)通过代理来调用被代理对象的方法

    静态代理demo:模拟通过代理租房

    1 package proxydemo;
    2 
    3 public interface HireHouse {
    4 
    5     public void hire();
    6 }
    HireHouse
     1 package proxydemo;
     2 
     3 public class HireHouseImpl implements HireHouse {
     4 
     5     @Override
     6     public void hire() {
     7         System.out.println("我要租房");
     8 
     9     }
    10 
    11 }
    HireHouseImpl

    代理类,实现HireHouse接口,持有代理对象(真实对象的引用)

     1 package proxydemo;
     2 
     3 public class HireHouseProxy implements HireHouse {
     4 
     5     private HireHouse hh;//代理对象,持有真实对象的引用
     6     
     7     
     8     public HireHouseProxy(HireHouse hh) {
     9         /*多态方式,接收接口的实现类对象,为静态代理,缺点是,只能给租房这件事做代理,
    10          *因为传递进来的是HireHouse这个接口的实现类对象 ,不能代理其他的事情*/
    11         super();
    12         this.hh = hh;
    13     }
    14 
    15 
    16     @Override
    17     public void hire() {
    18         System.out.println("收中介费");//代理做的事情
    19         hh.hire();//真实对象租房
    20         System.out.println("扣押金");//代理做的
    21 
    22     }
    23 
    24 }
    HireHouseProxy

    调用代理类:

     1 package proxydemo;
     2 
     3 public class Client {
     4 
     5     public static void main(String[] args) {
     6         HireHouse proxyHire = new HireHouseProxy(new HireHouseImpl());
     7         System.out.print("---通过代理租房:");
     8         proxyHire.hire();//通过代理租房
     9         System.out.print("---真实对象自己租房:");
    10         new HireHouseImpl().hire();//真实对象自己租房
    11         
    12     }
    13 }
    Client

     动态代理demo:

     1 package proxydemo.dynamic.proxy;
     2 /**
     3  * 真实对象和代理对象的共同接口,不仅仅能租房。
     4  * @author Administrator
     5  *
     6  */
     7 public interface HireHouse {
     8 
     9     public void hire();
    10 }

    接口实现类:

    1 package proxydemo.dynamic.proxy;
    2 
    3 public class HireHouseImpl implements HireHouse {
    4 
    5     @Override
    6     public void hire() {
    7         System.out.println("我要租房");
    8     }
    9 }

    代理类,实现InvocationHandler 接口

     1 package proxydemo.dynamic.proxy;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 
     6 /**
     7  * 实现InvocationHandler接口,通过反射去调用被代理的接口
     8  * @author Administrator
     9  * 
    10  */
    11 public class HireProxy implements InvocationHandler {
    12     // 被代理的真实角色
    13     private Object obj;// 真实角色,要给任何对象做代理,只能是持有Object类型的对象
    14     
    15     public HireProxy(Object obj) {
    16         super();
    17         this.obj = obj;
    18     }
    19 
    20 /**
    21  * jdk动态代理,被代理对象必须实现接口
    22  * 被代理的对象必然实现共同的Hire接口,那么就有方法
    23  * method:被代理的对象的接口中的方法,要调用方法,必须有对象,此处这个对象就是被代理对象,因此必须要指定被代理的对象
    24  * args是被代理对象接口的方法的参数,调用proxy对象的method方法
    25  */
    26     @Override
    27     public Object invoke(Object proxy, Method method, Object[] args)
    28             throws Throwable {
    29         System.out.println("前置工作");
    30 //        for (Object object : args) {
    31 //            System.out.print("invoke方法中的第三个参数:"+object +" ");//给list做代理时测试用
    32 //        }
    33         Object invoke = method.invoke(obj, args);
    34         System.out.println("
    后置工作");
    35         return invoke;
    36     }
    37 
    38 }

    动态代理测试:

     1 package proxydemo.dynamic.proxy;
     2 
     3 import java.lang.reflect.Proxy;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 public class Client {
     8 
     9     public static void main(String[] args) {
    10         // 创建被代理的接口实现类对象
    11          HireHouseImpl hhi = new HireHouseImpl();
    12          //创建代理对象:第一个参数是被代理的对象的类加载器,第二个是被代理对象的类的所有接口,第三个参数是自定义代理类的角色
    13          HireHouse hh =
    14          (HireHouse)Proxy.newProxyInstance(hhi.getClass().getClassLoader(),
    15          hhi.getClass().getInterfaces(), new HireProxy(hhi));
    16          hh.hire();
    17 
    18         // 给list做代理
    19 //        List list = new ArrayList();
    20 //        List hh1 = (List) Proxy.newProxyInstance(list.getClass()
    21 //                .getClassLoader(), list.getClass().getInterfaces(),
    22 //                new HireProxy(list));
    23 //        hh1.add("张三");
    24 //        hh1.get(0);//被代理对象的所有方法都被代理了
    25 
    26     }
    27 }
  • 相关阅读:
    最全前端面试题
    经常犯的思维误区
    鸿蒙系统发布会
    前端面试题
    怎么做一个竖排文字?
    canvas-台球玩法
    canvas-自由落体球
    canvas-画一颗心
    canvas-学写字
    常用的65条正则表达式
  • 原文地址:https://www.cnblogs.com/enjoyjava/p/8253992.html
Copyright © 2020-2023  润新知