java动态代理(JDK和cglib)

java动态代理(JDK和cglib)

JAVA的动态代理 
代理模式 :
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 
按照代理的创建时期,代理类可以分为两种。 
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 
动态代理:在程序运行时,运用反射机制动态创建而成。


一、JDK动态代理:

直接使用JDK-API;

只能为实现了接口的类创建代理对象(通过接口形式创建对象)。

/**

 * ①创建一个代理类JDKDynamicProxy实现InvocationHandler接口

 * ②实现接口中的invoke方法

 * ③在类中定义一个Object类型的属性,用来传递被代理对象

 * ④提供一个带有Object类型的构造器

 * ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象

 */


程序清单:
1.TestInterface接口

package com.softeem.dynamicproxy;

public interface TestInterface {
	public void test01();
}

2.TestInterface实现接口

package com.softeem.dynamicproxy;

public class TestImplement implements TestInterface {
	@Override
	public void test01() {
		System.out.println("这是JDK动态代理测试方法");
	}
}

3.JDK动态代理

package com.softeem.dynamicproxy;

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

/**
 * 直接使用JDK-API
 * 只能为实现了接口的类创建代理对象(通过接口形式创建对象)
 * ①创建一个代理类JDKDynamicProxy实现InvocationHandler接口
 * ②实现接口中的invoke方法
 * ③在类中定义一个Object类型的属性,用来传递被代理对象
 * ④提供一个带有Object类型的构造器
 * ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象
 */
public class JDKDynamicProxy implements InvocationHandler {

	private Object obj;
	
	public JDKDynamicProxy(Object obj) {
		this.obj = obj;
	}

	//获取代理对象
	public Object getProxy(){
		Object proxyObj = null;
		proxyObj = Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
		//要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
		return proxyObj;
	}


	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
			//tif.test01();第一个参数相当于tif,第二个参数相当于test01(),第三个参相当于参数
		
		System.out.println("-------");
		
		Object returnObj = method.invoke(obj, args);
		
		System.out.println("<><><><>");
		return returnObj;
	}

}

4.Test测试类

package com.softeem.dynamicproxy;

public class Test {
	
	public static void main(String[] args) {
		
		TestImplement ti = new TestImplement();
		
		//为ti对象创建代理对象
		Object obj = new JDKDynamicProxy(ti).getProxy();//obj只存在于内存的对象
		
		System.out.println(obj.getClass());
		
		//因为jdk动态代理是通过接口创建的代理对象
		TestInterface tif = (TestInterface) obj;
		//TestInterface tif2 = new TestImplement();
		//父类引用指向子类对象(多态),不能调用子类特有的方法,只能调用抽象方法中的类
		
		//通过代理对象调用方法时,实际上是调用类代理类中的invoke方法
		tif.test01();
	}
}


二、cglib动态代理

使用到类第三方jar包:CGLib.jar

不能为final类创建代理对象(通过子类创建代理对象)

/**

 * ①创建一个代理类CGLibDynamicProxy实现MethodInterceptor接口

 * ②实现intercept方法

 * ③在类中定义一个Object类型的属性,用来传递被代理对象

 * ④提供一个带有Object类型的构造器

 * ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象

 */

程序清单

1.cglib动态代理类CGLibDynamicProxy

package com.softeem.dynamicproxy;

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 使用到类第三方jar包:CDLib.jar
 * 不能为final类创建代理对象(通过子类创建代理对象)
 * ①创建一个代理类CGLibDynamicProxy实现MethodInterceptor接口
 * ②实现intercept方法
 * ③在类中定义一个Object类型的属性,用来传递被代理对象
 * ④提供一个带有Object类型的构造器
 * ⑤创建一个方法getProxy返回一个对象,即为被代理对象的代理对象
 */
public class CGLibDynamicProxy implements MethodInterceptor {

	private Object obj;
	
	public CGLibDynamicProxy(Object obj) {
		this.obj = obj;
	}

	public Object getProxy(){
		//通过创建被代理对象的子类,来为其创建代理对象
		Enhancer en = new Enhancer();
		en.setSuperclass(obj.getClass());
		en.setCallback(this);//回调
		
		return en.create();
	}

	/**
     * 在代理实例上处理方法调用并返回结果
     * 
     * @param proxy
     *            代理类
     * @param method
     *            被代理的方法
     * @param params
     *            该方法的参数数组
     * @param methodProxy
     * 			     代理的方法
     */
	@Override
	public Object intercept(Object arg0, Method method, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		System.out.println("-------");
		Object returnObj = method.invoke(obj, arg2);
		System.out.println("<<><><><><>>");
		return returnObj;
	}
}

2.CGLibTest测试类

package com.softeem.dynamicproxy;

public class CGLibTest {
	
	public static void main(String[] args) {
		
		TestImplement ti = new TestImplement();
		
		CGLibDynamicProxy cgdp = new CGLibDynamicProxy(ti);
		//创建ti的代理对象obj
		Object obj = cgdp.getProxy();
		
		//通过创建被代理对象类的子类来创建的代理对象
		//所以可以讲代理对象直接强转成被代理对象的类型
		TestImplement t = (TestImplement) obj;
		
		t.test01();
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章