现在的位置: 首页 > 综合 > 正文

jdk动态代理的实现

2013年12月06日 ⁄ 综合 ⁄ 共 2381字 ⁄ 字号 评论关闭

代理分为静态代理和动态代理,静态代理完全是一些硬编码操作,如果有介个接口,和他们的实现类,就要写多个代理器。很麻烦

动态代理步骤:

将接口A的实现类AImpl的类对象,实现的接口(class.getInterfaces()) 传给具体的封装好的类。

然后生成一个Aimpl的子类,重写父类中的方法,在这些方法中加入invoke(),在这invoke中调用的其实还是父类中的方法和另外一些添加的功能操作

创建出这个子类对象,调用子类的方法。

代码示例:

功能接口:

package dynamic;

/**
 * 功能方法
 * @author 追本溯源
 *
 */
public interface InterfaceTs {
	
	public void introduce(String speak);
	public void profession(String work);
	public void residence(String place);
}

接口实现类:

package dynamic;

public class InterfaceImpl implements InterfaceTs {

	public void introduce(String speak) {
		System.out.println("大家好,我是追本溯源,我是新手请多照顾");
	}

	public void profession(String work) {
		System.out.println("我从事J2EE");
	}

	public void residence(String place) {
		System.out.println("先居住地在杭州");
	}
	
}

动态代理实现:

package dynamic;

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


/**
 * 实现动态代理的接口
 * @author 追本溯源
 *
 */
public class JdbDynamicTs implements InvocationHandler{
	Object target = null;
	
	/**
	 * 
	 * @param clazz  target.class
	 * @return
	 */
	public Object bind(Class clazz){
		try {
			//反射对象,方便用户传递参数
			target = clazz.newInstance();
			
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		//this指的invoke 这是一个回调函数 将this传递到Proxy类,在newProxyInstance中调用这个接口的invoke方法
		//这里我要说下我的看法,下面的invoke(Object proxy..)这个proxy让我很无语,为什么不是target这个对象呢?
		//这里倒是没什么不方便,但是如果bind函数和invoke函数分开呢?还要还要在invoke所在的类中为target传参
		//还不如直接将invoke(Object target)这么改写,只要在Proxy.newProxyInstance中为其注入就行了
		//在Proxy类的newProxyInstance中传入了target的类加载器,可以动态生成子类,
		return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
	}
	/**
	 *  动态代理有什么用
	 *  想在一个实现好的类的方法中在添加一些功能,但是又不能在这些类上直接改写
	 *  那么就来用动态代理吧
	 */
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//我想另外添加的一些操作,比如说是日志的记录
		System.out.println(method.getName()+"执行前,我想添加的一些实现");
		//这里的target要注意了,不要写成proxy
		Object result = method.invoke(target, args);
		System.out.println(method.getName()+"执行后,我想添加的一些实现");
		return result;
	}

	
}

测试函数:

package dynamic;

public class MainTs {
	public static void main(String[] args) {
		JdbDynamicTs jdt = new JdbDynamicTs();
		//InterfaceTs是一个接口 InterfaceImpl是实现类
		InterfaceTs it = (InterfaceTs)jdt.bind(InterfaceImpl.class);
		//是不是很奇怪,下面方法执行后才会去回调invoke()
		//这里的it是动态产生的子类,里面的方法如introduce{invoke()}。放进里面了
		it.introduce("");
		it.profession("");
		it.residence("");
	}
}

结果:

java.lang.reflect.InvocationHandler
introduce执行前,我想添加的一些实现
大家好,我是追本溯源,我是新手请多照顾
introduce执行后,我想添加的一些实现
profession执行前,我想添加的一些实现
我从事J2EE
profession执行后,我想添加的一些实现
residence执行前,我想添加的一些实现
先居住地在杭州
residence执行后,我想添加的一些实现

很简单吧&_^

抱歉!评论已关闭.