代理模式之动态代理

动态代理(Dynamic Proxy):

两种机制:JDK  CGLIB

    对比:
        JDK只能代理实现了接口的类(聚合)
        CGLIB针对类来实现代理,产生目标类的子类,覆盖目标类的某些方法,从而实现代理(继承)
 

一、JDK动态代理

1、动态代理类:
      1> 它是在运行时生成的class
      2> 该class需要实现一组interface
      3> 使用动态代理类时,必须实现Invocationhandler接口(这里实现具体的代理业务功能)

2、动态代理实现步骤:
      1> 创建一个实现接口InvocationHandler的类,它必须实现invoke方法.
      2> 创建被代理的类以及接口
      3> 调用Proxy的静态方法,创建一个代理类
         newProxyInstance(loader,interfaces,h)
      4> 通过代理调用方法

1)TimeHandler.java

   package com.zy.jdkproxy;

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;

	/**
	 * proxy 被代理对象 method 被代理对象的方法 args 方法的参数
	 * 
	 * 返回值: 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) + "毫秒");
		// move方法没有返回值则返回null
		return null;
	}

}

2)Test.java 测试类

package com.zy.jdkproxy;

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

import com.zy.proxy.Car;
import com.zy.proxy.Moveable;

public class Test {

	/**
	 * JDK动态代理测试类
	 */
	public static void main(String[] args) {

		Car car = new Car();
		// 获取时间代理对象
		InvocationHandler h = new TimeHandler(car);
		// 获取别代理类的类加载器
		Class<?> cls = car.getClass();

		/**
		 * Proxy.newProxyInstance(loader, interfaces, h); 
		 * loader:类加载器 
		 * interfaces 实现接口
		 * h InvocationHandler
		 */
		//动态获取代理类
		Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), h);
		m.move();
	}

}

二、CGLIB动态代理

      实现步骤:

      1> 创建被代理的类
      2> 创建一个实现接口MethodInterceptor的类,它必须实现intercept方法,对代理类方法进行拦截并加入代理业务功能代码.并且创建一个根据属性产生代理类的getProxy方法.
      3> 新建代理类,通过代理类调用方法
 
1) Train.java 

package com.zy.cglibproxy;

public class Train {

	public void move() {
		System.out.println("火车行驶中...");
	}
}

2) CglibProxy.java

package com.zy.cglibproxy;

import java.lang.reflect.Method;

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

public class CglibProxy implements MethodInterceptor {

	// 创建代理类的属性
	private Enhancer enhance = new Enhancer();

	// 产生指定类的代理类
	public Object getProxy(Class clazz) {
		// 设置产生子类的类(即为那个类创建代理类)
		enhance.setSuperclass(clazz);
		// 设置回调
		enhance.setCallback(this);
		// 创建对应属性的代理类并返回
		return enhance.create();
	}

	/**
	 * 拦截所有目标类方法的调用 obj 目标类的实例 m 目标方法的反射对象 args 方法的参数 proxy 代理类的实例
	 */


	@Override
	public Object intercept(Object obj, Method m, Object[] args,MethodProxy proxy) throws Throwable {
		System.out.println("日志开始...");
		// 代理类调用父类的方法
		proxy.invokeSuper(obj, args);
		System.out.println("日志结束...");
		return null;
	}


}

3) Test.java 测试类

package com.zy.cglibproxy;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		CglibProxy proxy = new CglibProxy();
		Train t = (Train) proxy.getProxy(Train.class);
		t.move();
	}

}



你可能感兴趣的:(动态代理,jdk,代理模式)