首页 > 文章列表 > Java代理模式实例代码分析

Java代理模式实例代码分析

java
232 2023-05-06

Java代理模式实例代码分析

1、动态代理模式

动态代理的特点:

  • 当代理对象的时候,不需要实现接口

  • 代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)

动态代理的别称:JDK代理、接口代理

2、JDK动态代理

类图:

Java动态代理类位于java.lang.reflect包下

一般主要涉及到以下两个类:

1、Interface InvocationHandler : 该接口中仅定义了一个方法public object invoke(Object obj,Method method, Object[] args) 在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组。这个抽象方法在代理类中动态实现。

2、Proxy:该类即为动态代理类

static Object newProxyInstance(ClassLoader loader, Class[] interfaces,InvocationHandler h):

返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在接口中声明过的方法)

动态代的实现步骤:

  • 创建一个实现接口InvocationHandler的类,它必须实现invoke方法

  • 创建被代理的类以及接口

  • 调用Proxy的静态方法,创建一个代理类:newProxyInstance(ClassLoader loader,Class[]

  • 通过代理调用方法

3、JDK动态代理代码演示

比如现在有一个汽车驾驶的方法:

public interface Moveable {

    void move();

}

现在有一辆汽车:

//实现Moveable 接口,并随机暂停一段时间



import java.util.Random;

public class Car implements Moveable{

    @Override

    public void move() {

        try{

            Thread.sleep(new Random().nextInt(1000));

            System.out.println("汽车行驶中");

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

}

时间代理类:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;



public class TimeHandler implements InvocationHandler{



    public TimeHandler(Object target){

        super();

        this.target = target;

    }

    private Object target;





    /**

     *

     * @param proxy :被代理的对象

     * @param method:被代理对象的方法

     * @param args:方法的参数

     * @return

     * @throws Throwable

     * 返回值:Object 方法的返回值

     */

    @Override

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

        long startTime = System.currentTimeMillis();

        System.out.println("汽车开始行使");



        method.invoke(target);



        long endTime = System.currentTimeMillis();

        System.out.println("汽车行驶结束,行驶的时间为:"+(endTime-startTime)+"毫秒");

        return null;

    }

}

测试类:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;



public class Test {

    public static void main(String[] args) {



        Car car = new Car();

        InvocationHandler h = new TimeHandler(car);

        Class<?> cls = car.getClass();



        /**

         * newProxyInstanced的参数

         * 分别是:类加载器、实现的接口、实现的处理器

         */

        Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(),

                cls.getInterfaces(),h);

        m.move();

    }

}

这样的输出结果是:

汽车开始行使

汽车行驶中

汽车行驶结束,行驶的时间为:137毫秒

//后面的时间是随机产生的,每次都不一样

注意:

JDK代理只能代理实现了接口的类,没有实现接口的不能代理

cglib是针对类来实现代理的,cglib的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理,因为小应学长自己对这一块也没有完全掌握,这里就不多讲解,大家可以参考其他博主的技术文章。