静态代理和JDK动态代理及cglib动态代理

package com.proxy;

import java.util.Random;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Car implements MoveAble {

    @Override
    public void move() {

        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}


package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Car2 extends Car {
    public void move(){
        long starttime=System.currentTimeMillis();
        System.out.println("汽车开始行驶...");
        super.move();
        long endtime=System.currentTimeMillis();
        System.out.println("汽车结束行驶... 汽车行驶时间:" + (endtime - starttime) + "ms");

    }
}
package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Car3 implements MoveAble {
    private Car car;

    public Car3(Car car) {
        super();
        this.car = car;
    }

    @Override
    public void move() {
        long starttime=System.currentTimeMillis();
        System.out.println("汽车开始行驶...");
        car.move();
        long endtime=System.currentTimeMillis();
        System.out.println("汽车结束行驶... 汽车行驶时间:" + (endtime - starttime) + "ms");
    }
}
package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Client {
    public static void main(String[] args) {
       /* Car car=new Car();
        car.move();*/
        /**使用集成方法
         * MoveAble moveAble=new Car2();
         moveAble.move();*/

        //使用聚合方式实现
        Car car=new Car();
        MoveAble moveAble=new Car3(car);
        moveAble.move();
    }
}
package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public interface MoveAble {
    public void move();
}


使用聚合的方式实现代理的好处是多态

实现功能的叠加:

package com.proxy;

import java.util.Random;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Car implements MoveAble {

    @Override
    public void move() {

        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}
package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class CarLogProxy implements MoveAble {
    /**
     * 因为代理类和被代理类都是实现了相同的接口,所以构造方法传递的参数可以是MoveAble对象
     */
    private MoveAble moveAble;

    public CarLogProxy(MoveAble moveAble) {
        super();
        this.moveAble=moveAble;
    }

    @Override
    public void move() {
        long starttime=System.currentTimeMillis();
        System.out.println("日志开始...");
        moveAble.move();
        long endtime=System.currentTimeMillis();
        System.out.println("日志结束:" + (endtime - starttime) + "ms");
    }
}
package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class CarTimeProxy implements MoveAble {
    /**
     * 因为代理类和被代理类都是实现了相同的接口,所以构造方法传递的参数可以是MoveAble对象
     */
    private MoveAble moveAble;

    public CarTimeProxy(MoveAble moveAble) {
        super();
        this.moveAble=moveAble;
    }

    @Override
    public void move() {
        long starttime=System.currentTimeMillis();
        System.out.println("汽车开始行驶...");
        moveAble.move();
        long endtime=System.currentTimeMillis();
        System.out.println("汽车结束行驶... 汽车行驶时间:" + (endtime - starttime) + "ms");
    }
}
package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Client {
    public static void main(String[] args) {
        Car car=new Car();
        CarTimeProxy ctp=new CarTimeProxy(car);
        CarLogProxy clp=new CarLogProxy(ctp);
        clp.move();

    }
}
package com.proxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public interface MoveAble {
    public void move();
}


时间代理和日志代理都是实现相同的接口,如果不同的类需要这些时间代理和日志代理,如何将他们统一,用一个TimeProxy实现对小汽车,自行车的动态代理,如下:

JDK动态代理

package com.jdkproxy;

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

/**
 * Created by 79782 on 2018/6/30.
 */
public class LogHandler implements InvocationHandler {
    private Object target;

    public LogHandler(Object target) {
        this.target = target;
    }

    /**
     *
     * @param proxy 被代理的对象
     * @param method 被代理动向的方法
     * @param args 方法的参数
     * @return Object
     * @throws Throwable
     */
    @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) + "ms");
        return null;
    }
}
package com.jdkproxy;

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

/**
 * Created by 79782 on 2018/6/30.
 */
public class TimeHandler implements InvocationHandler {
    private Object target;

    public TimeHandler(Object target) {
        this.target = target;
    }

    /**
     *
     * @param proxy 被代理的对象
     * @param method 被代理动向的方法
     * @param args 方法的参数
     * @return Object
     * @throws Throwable
     */
    @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) + "ms");
        return null;
    }
}
package com.jdkproxy;

import com.proxy.Car;
import com.proxy.MoveAble;

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

/**
 * Created by 79782 on 2018/6/30.
 */
public class Test {
    public static void main(String[] args) {
        Car car=new Car();
        InvocationHandler timeHandler=new TimeHandler(car);
        /**
         * loader:类加载器
         * interfaces:实现接口
         * h InvocationHandler
         */
        Class<?> cls=car.getClass();
        MoveAble moveAble=(MoveAble)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), timeHandler);

        InvocationHandler logHandelr=new LogHandler(moveAble);
        MoveAble m2=(MoveAble)Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), logHandelr);
        m2.move();
    }
}


JDK动态代理:

1.只能代理实现了接口的类。

2.没有实现接口的类不能实现JDK的动态代理。

Cglib动态代理:

1.针对类来实现代理。

2.对指定目标类产生一个子类,通过方法拦截技术拦截所有父类方法的调用。

3.因为是使用继承的方式,所以不能对final修饰的类进行代理。

使用Cglib实现动态代理:

<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
  <version>3.2.3</version>
</dependency>
package com.cglibproxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Created by 79782 on 2018/6/30.
 */
public class CglibProxy implements MethodInterceptor {
    private Enhancer enhancer=new Enhancer();
    public Object getProxy(Class clzz){
        //设置创建子类的类
        enhancer.setSuperclass(clzz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    /**
     * 拦截所有目标类方法的调用
     * @param o 目标类的实例
     * @param method 目标方法的反射对象
     * @param objects 方法的参数
     * @param methodProxy 代理类的实例
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("日志开始...");
        //代理类调用父类的方法
        methodProxy.invokeSuper(o,objects);
        System.out.println("日志结束...");
        return null;
    }
}
package com.cglibproxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Train {
    public void move(){
        System.out.println("火车行驶中...");
    }
}
package com.cglibproxy;

/**
 * Created by 79782 on 2018/6/30.
 */
public class Client {
    public static void main(String[] args) {
        CglibProxy proxy=new CglibProxy();
        Train t=(Train)proxy.getProxy(Train.class);
        t.move();
    }
}

JDK动态代理可以对实现某一接口的任意类,任意方法产生任意的代理。

动态代理实现思路:通过Proxy的newProxyInstance返回代理对象

动态代理实现思路:

1.声明一段源码(动态产生代理)

2.编译源码,产生新的类(代理类)

3.将这个类load到内存中,产生一个新的对象(代理对象)

4.return代理对象

猜你喜欢

转载自blog.csdn.net/weixin_40839342/article/details/80863841
今日推荐