码迷,mamicode.com
首页 > 编程语言 > 详细

java动态代理(JDK和cglib)

时间:2014-08-29 02:58:37      阅读:247      评论:0      收藏:0      [点我收藏+]

标签: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 {
		
		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包:CDLib.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();
	}

	@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();
	}
}


本文出自 “黑足Sanji” 博客,谢绝转载!

java动态代理(JDK和cglib)

标签:java动态代理(jdk和cglib)

原文地址:http://974124461.blog.51cto.com/8685015/1546310

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!