仿JDK动态代理实现

下面我模仿了一下JDK动态代理的实现,源码没看,这里不不过是根据他的功能按照自己的方式实现.


使用技术

关键是回调函数的使用。


文档:

我们既然使用动态代理无非想在现有的方法中添加一些操作。所以在创建的子类方法中调用回调函数。

创建子类涉及动态字节码技术,我就写死一个subclass代替

创建Proxy类负责创建子类对象


一:回调函数模块:

1:创建接口

package callback;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public interface CallBackInterface {
	
	public Object callback(Method method,Object obj,Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;

}


2:用户对接口的实现:

package callback;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class ClientTs implements CallBackInterface{

	
	/** 回调函数**/
	public Object callback(Method method, Object obj, Object[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		System.out.println("事务处理执行");
		Object result = method.invoke(obj, args);
		System.out.println("事务处理结束");
		return result;
	}
	
	
	
}

3:服务实现:

package callback;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class CallBackTs {
	
	private CallBackInterface cbi;
	
	
	public CallBackTs(CallBackInterface cbi){
		this.cbi = cbi;
	}
	
	/** 
	 * 调用client中的callback()函数
	 * 具体的子类,其实现的方式不同
	 */
	public Object interceptor(Method method, Object obj, Object[] args){
		Object result = null;
		try {
			result = cbi.callback(method, obj, args);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return result;
		
	}
}

二:代理模块

1:业务接口:    其实不使用接口也是 可行的

package callback;

public interface FatherInter {
	
	public void add(String name,String love);
	public void answer(String text);
}

2:接口实现类:

package callback;

public class Father implements FatherInter{
	
	public void add(String name,String love){
		System.out.println("My name is "+name);
		System.out.println("and My favorites are "+love);
	}
	public void answer(String text){
		System.out.println("did you feel surprise about "+text);
	}
}

3:创建father的子类:

package callback;

import java.lang.reflect.Method;

/**
 * SubClassTs 是Father模拟的动态子类 FatherInter是他们的接口
 * @author 追本溯源
 *
 */
public class SubClassTs extends Father implements FatherInter {
	private Object target;
	private CallBackTs cbt = null;
	public SubClassTs(CallBackTs cbt,Object target){
		this.cbt = cbt;
		this.target = target;
	}
	public void add(String name,String love){
		try {
			//本以为extends Father
			//this.add指的是被覆盖的当前add,递归,死循环
			//this.add("one", "two");
			Method method = target.getClass().getMethod("add", new Class[]{String.class,String.class});
			Object[] args = {name,love};
			cbt.interceptor(method, target, args);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
	
	public void answer(String text){
		try {
			Method method = target.getClass().getMethod("answer", new Class[]{String.class});
			Object[] args = {text};
			cbt.interceptor(method, target, args);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}
	}
}


4:创建Proxy类实现子类的创建:

package callback;

public class Proxy {
	
	/** 创建子类对象*
	 * @throws IllegalAccessException 
	 * @throws InstantiationException */
	public static Object newProxy(CallBackInterface cif,Class clazz) throws InstantiationException, IllegalAccessException{
		CallBackTs cbt = new CallBackTs(cif);
		return new SubClassTs(cbt,clazz.newInstance());
	}
}

5:创建对象并测试:

package callback;

public class ProxyTs {
	
	
	public static Object getProxyTs(Class clazz){
		//这里简单的创建子类SubClass对象
		Object obj = null;
		try {
			obj = Proxy.newProxy(new ClientTs(),clazz);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return obj;
	}
	
	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		
		FatherInter father =  (FatherInter) ProxyTs.getProxyTs(Father.class);
		father.add("追本溯源", "写代码");
		father.answer("前途渺茫");
	}
}

结果:

事务处理执行
My name is 追本溯源
and My favorites are 写代码
事务处理结束
事务处理执行
did you feel surprise about 前途渺茫
事务处理结束

有很多要该进的地方,至少和cglib类中Enhancer差距还是非常大的。



你可能感兴趣的:(仿JDK动态代理实现)