动态代理课堂笔记

代理模式和动态代理:
掌握:代理的作用,动态代理能什么。不用关心技术的实现细节。
后面会将框架,mybatis ,spring 他们都用到了动态代理的概念。

概念:
设计模式:指java中解决某些问题模板。 是前辈经验的总结。用来解决某些问题的。
单例模式, 模板模式等等。
代理模式:当你需要访问一个对象,这个对象因为某种原因不能直接访问,需要通过另一个对象间接访问。
这个间接对象就是代理。这种对象的访问方式就是代理模式的使用。

	   对象C, 使用A访问C , 正常A可以访问C。 现在C不让A访问,但可以让B访问。
	   此时A需要访问,借助B实现, A--->B--->C, 此时B代理C的对外访问功能。
	   B就是A和C之间的代理。

日常生活中的代理:
1.房屋中介
2.代购
3.留学中介。

代理模式作用:
1.增强功能:在通过商场买东西时,可以加价。还可以返红包。
2.控制访问: 控制对目标方法的调用, 用户不能直接访问工厂。

代理模式分类:
1.静态代理:代理类和目标类的关系已经确定的, 在程序执行之前,关系已经确定的。
2.动态代理:在程序执行过程中确定代理和目标关系的,并且能够创建出代理对象。
动态代理中能够创建对象,这是他的重要能力。这个对象是代理对象


静态代理优点: 结构简单,容易理解,代理的目标类是固定的。
静态代理缺点: 1.当目标类比较多,会造成代理类数量庞大,类越多难以管理。
2.当接口中方法有修改,会造成所有的目标类和代理类都发生修改。

静态代理的适用条件:目标类比较少, 代理类也不多。

====================================================================================

动态代理: 使用反射机制创建代理对象。 在程序执行过程中确定代理和目标类的关系。
并创建内存中的代理对象。 通过这个代理对象能调用目标方法并增强功能。

		动态代理就是在程序执行时,使用反射机制创建类似TaoBao类,并创建TaoBao类的对象。
		这个对象只存在内存中。 实现TaoBao类的功能。
		
		动态代理是创建对象的一种能力。 创建的是代理类的对象。

java中创建对象有哪些方式:
1. 使用new 创建对象
2. 使用反射机制 , Class.forName(“com.wkcto.entity.Student”).newInstance();
3. 使用序列化和反序列化
4. 读取二进制文件

动态代理特点:
1.代理对象(TaoBao)是存在内存中的,不需要写java文件,不需要编译class文件。
这个对象可以使用jdk的方法帮你创建好。
2.可以在程序中,组合目标类,给不同的目标类创建出代理对象。这样你的程序中没有那么多的类了。
3.当目标类的接口发生变化,不影响动态代理对象。

动态代理实现方式:
1.使用jdk中的反射机制实现,叫做jdk动态代理(重点)
2.使用第三方的工具库,叫做cglib。 也叫做cglib动态代理。
cglib创建代理的原理是:继承。 同继承目标类,在子类中重写方法的代理,实现代理类的功能。
这个子类就是代理。 因为cglib使用继承方式,所以目标类不能使用final修饰,方法也不能是final的

使用jdk的反射机制,创建对象(内存中的代理对象):
1.接口InvocationHandler (调用处理器)
调用处理器作用:完成代理对象的功能,也就是代理类要做什么。
具体使用是:定义类实现InvocationHandler 接口,这个接口中就一个方法invoke().
需要重写方法invoke(). 在invoke()方法中,主要作两件事情
1.调用目标方法 ,例如: float price = kingFactory.sell(1000);
2.增强功能,例如 price = price + 25; System.out.println(“TaoBao代理类实现了红包的返现功能”);

例如: class MyInvocation implements InvocationHandler{
          public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
		  
		    1.调用目标方法 ,例如: float price = kingFactory.sell(1000);
			                        method.invoke(目标对象需要赋值,args)
		    2.增强功能,例如   price = price + 25; System.out.println("TaoBao代理类实现了红包的返现功能");
		  }

        }


jdk会调用invoke()方法,实现代理类要执行的功能

2.Method类:表示方法的。表示任何的方法。
动态代理,在程序执行时确定目标对象的, 当我们编写invoke()方法时,还不知道目标对象,也不知道目标方法叫什么名字

class OrderService{

 private String orderName; //订单名称
 public void createOrder(){ //创建订单
 
 }

}

Class clazz = OrderService.class
Method [] method = clazz.getMethod();

Method == createOrder();

java中使用反射机制得到Method,可以表示方法,也可以执行方法。
Method类有一个内部自己的方法invoke().

invoke()格式:
public Object invoke(Object obj, Object… args)
方法的参数说明:Object obj 表示一个java对象 , Method表示obj中一个方法
Object… args:Method表示的方法执行时的实参

怎么使用Method类的invoke()执行目标方法,达到float price = kingFactory.sell(1000);这个方法调用的功能呢。
做法: method.invoke(目标对象,参数)

3.创建代理对象。使用jdk中的静态方法,使用Proxy类的newProxyInstance()方法。
Proxy.newProxyInstacne()方法的作用:使用反射机制创建代理类的对象。就是相当于(TaoBao taobao = new TaoBao() )

方法定义:
public static Object newProxyInstance( ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)

使用这三个参数,创建代理对象的。 理解上newProxyInstance就相当于一个工厂,比如这个工厂是生产水果罐头的。
可以桃的罐头, 橘子的罐头等等

生产罐头需要原材料, 方法的参数就是原材料。有哪些材料:
ClassLoader loader:类加载器,目标类的类加载类。找到目标对象,需要使用目标对象的信息。
Class<?>[] interfaces: 目标类实现的接口,需要接口信息。指定接口中的方法。
InvocationHandler h:表示代理类要执行的功能

使用上面的材料,生产出目标对象的代理对象。

实现动态代理的步骤:
1.创建目标类要实现的接口,定义功能
2.创建InvocationHandler接口的实现类,完成代理的功能
3.使用Proxy.newProxyInstacne方法,创建代理对象
4.把3中的代理对象强制转为接口的类型

==============================================================
使用代理购买u判断,请求的流程是:
用户购买—TaoBao代理—访问目标类的方法UsbKingFactory.sell()

注意:通过代理对象才能访问目标方法,执行期望的功能。

动态代理:解决静态代理中类比较多,接口方法修改会影响很多类这些缺点的。
动态代理就是说不能你创建TaoBao这样的类,不用定义TaoBao的java文件。 使用jdk中通过的功能
处理代理类对象, 使用jdk创建一个拥有TaoBao类功能的对象。 而这个对象的创建内部都实现好了。

使用jdk动态代理的实现: jdk动态代理就是使用java.lang.reflect反射包中的类和接口来实现创建对象的能力
1)InvocationHandler接口:调用处理器,访问代理类功能的(1.调用目标类的方法;2.增强功能)
2) Method类:执行目标方法, method.invoke(目标对象,方法参数); 因为动态代理中目标类是不确定的。
只有在程序执行时,才知道目标是谁,
3) Proxy.newProxyInstance: 创建代理对象.
创建代理需要指定的必要信息:
1. 要实现的接口(UsbSell)
2. 目标对象
3. 代理执行的功能代码

================================================================
动态代理底层的实现:
创建对象,必须有的类(class文件) ,通过这个class文件才能创建对象。
jdk的动态代理如何创建代理对象:1)创建类一个class文件;2)使用这个class创建对象
jdk动态代理把上面两个步骤隐藏起来了,不需要过问。

分析:
1) 使用 UsbSell proxy = (UsbSell) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
handler
);
创建的proxy对象是 com.sun.proxy. P r o x y 0 这 个 类 型 的 。 也 就 是 相 当 于 Proxy0 这个类型的。 也就是相当于 Proxy0Proxy0 proxy = new …();

    proxy是代理, 如果和静态代理对比 proxy应该是 TaoBao taobao =new TaoBao()中的taobao对象
    
    可以看做  proxy == taobao   , $Proxy0 和TaoBao 类似的
  1. 执行方法 taobao.sell(1) 执行的
    sell是实现的UsbSell接口中的方法
    public float sell(int amount) {
    //通过代理访问目标类的方法, 实现卖u盘功能
    float price = kingFactory.sell(1000);

    //代理类需要增加价格,25 增值。
    price = price + 25;

    //代理中给用户返回一个红包。0.1元
    System.out.println(“TaoBao代理类实现了红包的返现功能”);
    return price;
    }

----------------------------------------------------
proxy.sell(1)执行的是 invoke();

public class MyInvocation implements InvocationHandler {

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object result= null;
    //1.执行目标方法。使用参数Method
    result = method.invoke(target,args);//表示执行target目标对象的method方法
    //2.增强功能
        System.out.println("代理类实现返红包功能");
    return result;
}

 //目标对象
private Object target;
//传入那个目标,就创建这个目标对象的代理对象
public MyInvocation(Object target) {
    this.target = target;
}

}


3.)com.sum.proxy.$Proxy0类的定义, 这个类等同于TaoBao

proxy.sell(1)执行的是 InvocationHandler.invoke()方法
1.类定义 :class $Proxy0 extends Proxy implements UsbSell
2.实现UsbSell接口中的sell()方法

  public final float sell(int var1) throws  {
    try {
        return (Float)super.h.invoke(this, m4, new Object[]{var1});
        这里执行的是方法调用 super.h.invoke(); 
        super表示父类(Proxy),
        h:父类中的一个对象(InvocationHandler)
        invoke():应该是h的一个方法
        
        //super.h.invoke() 就是 InvocationHandler.invoke()
        
        
    } catch (RuntimeException | Error var3) {
        throw var3;
    } catch (Throwable var4) {
        throw new UndeclaredThrowableException(var4);
    }
}

总结一下:jdk动态代理
1。jdk创建一个 类叫做 P r o x y 0 , 实 现 了 U s b S e l l 接 口 2. 创 建 了 Proxy0, 实现了UsbSell接口 2. 创建了 Proxy0,UsbSell2.Proxy0类的对象, 叫做proxy
3. 通过代理对象 proxy执行sell方法时。
在sell()方法中会执行 InvocationHandler.invoke()
所有执行sell就是InvocationHandler的invoke()方法。
4.动态代理是创建对象能力,创建的 P r o x y 0 的 对 象 , 这 个 Proxy0的对象,这个 Proxy0Proxy0相当于是 TaoBao类
动态代理可以创建接口的实现类对象。实现类对象要完成的功能是InvoationHandler的invoke()方法中完成的。

  ![代理执行图](https://img-blog.csdnimg.cn/20200302150704412.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0pXNjE0NzE4,size_16,color_FFFFFF,t_70)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值