百木园-与人分享,
就是让自己快乐。

【JavaWeb】JDK动态代理 --- 代理模式;静态代理;动态代理;JDK动态代理的实现及实现原理分析

需要掌握的程度:


1. 什么是JDK动态代理 ?

使用jdk的反射机制,创建对象的能力(创建的是代理类的对象),而不用创建类文件,不用写java文件。

  • 动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。
  • jdk动态代理,必须有接口,目标类必须实现接口, 没有接口时,需要使用cglib动态代理。

2. 知道动态代理能做什么?

可以在不改变原来目标方法功能的前提下, 可以在代理中增强自己的功能代码。

 

代理模式:


1.代理:代购, 中介,换ip,商家等等。

  • 比如有一家美国的大学, 可以对全世界招生。 
  • 留学中介(代理): 帮助这家美国的学校招生,  中介是学校的代理, 中介是代替学校完成招生功能。

为什么要找中介 ?

  • 中介是专业的, 方便。
  • 家长现在不能自己去找学校。 家长没有能力访问学校。 或者美国学校不接收个人来访。

买东西都是商家卖, 商家是某个商品的代理, 你个人买东西, 肯定不会让你接触到厂家的。

2. 在开发中也会有这样的情况:

  • a类, 本来要调用c类的方法, 完成某个功能,但是c不让a调用。 

解决方案:

  • 在 a 和 c 直接 创建一个 b 代理, c 让 b访问。

        a --- 访问b --- 访问c

3.使用代理模式的作用

  • 功能增强: 在你原有的功能上,增加了额外的功能。 
  • 控制访问: 代理类不让你访问目标,例如商家不让用户访问厂家。 

静态代理 :  


  • 代理类是自己手动实现的,自己创建一个java类,表示代理类;同时你所要代理的目标类是确定的。

优点: 实现简单;容易理解。

缺点:当你的项目中,目标类和代理类很多的时候:

1)当目标类增加了, 代理类可能也需要成倍的增加,代理类数量过多。

2)当你的接口中功能增加了, 或者修改了,会影响众多的实现类,厂家类,代理类都需要修改,影响比较多。

 

动态代理:


  • 在程序执行过程中,使用jdk的反射机制,创建代理类对象, 并动态的指定要代理目标类;换句话说: 动态代理是一种创建java对象的能力,让你不用创建代理类,就能创建代理类对象。

优点:

1)代理类数量可以很少。

2)当你修改了接口中的方法时,不会影响代理类。

动态代理的实现:

  • jdk 动态代理(理解):使用 java 反射包中的类和接口(InvocationHandler , Method, Proxy)实现动态代理的功能。

 

  • cglib动态代理(了解): cglib是第三方的工具库,cglib的原理是继承, cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法, 实现功能的修改。

                                            由于cglib是继承,重写方法,所以要求目标类不能是final的, 方法也不能是final的。

                                            cglib的要求目标类比较宽松, 只要能继承就可以了。cglib在很多的框架中使用,比如 mybatis ,spring框架中都有使用。

 

jdk 动态代理实现步骤:


1、创建接口,定义目标类要完成的功能:

//目标接口
public interface UsbSell {
    float sell(int amount);
}

 

2、创建目标类实现接口:

//目标类
public class UsbKingFactory implements UsbSell {
    @Override
    //目标方法
    public float sell(int amount) {
        //厂家卖85.6元
        return 85.6f;
    }
}

 

3、创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能:

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;

        //执行目标方法
        res =  method.invoke(target,args);

        //商家需要加价(功能增强)
        if( res != null ){
            Float price = (Float)res;
            price = price + 25;
            res = price;
        }

        //再送你一张优惠券(功能增强)
        System.out.println(\"谢谢惠顾,送您一张优惠券,亲!\");

        //增加的价格
        return res;
    }
}

 

4、使用Proxy类的静态方法,创建代理对象。 并把返回值转为接口类型:

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

public class MainShop {
    public static void main(String[] args) {
        //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);
    }
}

 

JDK动态代理执行流程 :

【JavaWeb】JDK动态代理 --- 代理模式;静态代理;动态代理;JDK动态代理的实现及实现原理分析

                                      


来源:https://www.cnblogs.com/Burning-youth/p/16165448.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » 【JavaWeb】JDK动态代理 --- 代理模式;静态代理;动态代理;JDK动态代理的实现及实现原理分析

相关推荐

  • 暂无文章