动态代理

既然是代理,那么它与静态代理的功能与目的是没有区别的,唯一有区别的就是动态与静态的差别。

静态代理需要我们手动编写代码让 TaoBao实现 UsbSell接口,而在动态代理中,我们可以让程序在运行的时候自动在内存中创建一个实现 UsbSell接口的代理,而不需要去定义 TaoBao这个类。这就是它被称为动态的原因。

动态代理是利用的反射机制动态地生成代理的对象,我们不需要知道谁代理谁。代理类的那部分代码被固定下来了,不会因为业务的增加而逐渐庞大。

可以实现AOP编程

解耦

 使用jdk的反射机制,创建对象的能力,创建的是代理类的的对象.而不用我们创建类文件,不用写java文件, 什么叫动态?在程序执行时,调用jdk提供的方法才能创建代理类的对象

也就是说,不再需要手动的去创建静态代理的步骤中的TaoBao这样的代理类对象了

动态代理是一种创建java对象的能力,让你不用创建 TaoBao类就能创建代理类对象,除去了中间商

 

 

  1. 动态代理是指代理类对象在程序运行时由JVM根据反射机制动态生成的。动态代理不需要定义代理类的,java源文件。
  2. 动态代理其实就是jdk运行期间,动态创建class字节码并加载到JVM。
  3. 动态代理的实现方式常用的有两种:使用JDK代理,与通过CGLlB动态代理。

实现步骤
1.创建一个接口,定义卖u盘的方法,表示你的厂家和商家做的事情

package com.动态代理.service;

//目标接口
public interface UsbSell {

    float sell(int amount);

}

2.创建厂家类,实现1步骤的接口

package com.动态代理.factory;

import com.动态代理.service.UsbSell;

//目标类
public class UsbKingFactory implements UsbSell {
    @Override
    public float sell(int amount) {
        //目标方法
        System.out.println("目标类中,执行sell目标方法");


        return 85.0f;
    }
}

3.创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能。创建的即为商家,就是代理,也需要实现1步骤中的接口

package com.动态代理.handler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//必须实现的InvocationHandler接口,完成代理类要做的功能(1.调用目标的方法。2.功能增强)
public class MySellHandler implements InvocationHandler {

    private Object target = null;

    //动态代理:目标是活动的,不是固定的,需要传入进来。
    //传入是谁,就给谁创建代理。
    public MySellHandler(Object target) {
        //给目标对象赋值
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Object res = null;

        //向厂家发送订单,告诉厂家,我买了U盘,厂家发货
        //float price = factory.sell(amount);//厂家的价格
        res = method.invoke(target, args);//执行目标方法



        //商家需要加价,也就是代理要增加价格。
        //price = price + 25;//增强功能,代理类在完成目标类方法调用后,增强了功能。
        if (res != null){
            Float price = (Float) res;
            price = price + 25;
            res = price;
        }

        //在目标类的方法调用后,你做的其它功能,这都是增强的意思。
        System.out.println("淘宝商家,给你返回一个优惠券,或者红包");

        //增加价格
        return res;
    }
}

4.使用Proxy类的静态方法,创建代理对象,并把返回值转换成接口类型

即创建客户端类,调用商家的方法买一个u盘

package com.动态代理;

import com.动态代理.factory.UsbKingFactory;
import com.动态代理.handler.MySellHandler;
import com.动态代理.service.UsbSell;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class MainShop {

    public static void main(String[] args) {
        //创建代理对象,使用Proxy
        //1.创建目标对象
        UsbSell factory = new UsbKingFactory();
        //2.创建InvocationHandler对象
        InvocationHandler handler = new MySellHandler(factory);

        //3.创建代理对象
        UsbSell proxy = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(),
                handler);

        //4.通过代理执行方法
        float price = proxy.sell(1);
        System.out.println("通过动态代理对象调用方法: " + price);

    }

}

  

 

posted @ 2021-01-13 20:22  莫困顿  阅读(112)  评论(0编辑  收藏  举报