首页 > 技术文章 > aop动态代理底层实现模拟

yunianzeng 2020-02-13 03:37 原文

UserDAO.java:目标方法

public class UserDAO implements IDAO{
	@Override
	public void save() {
		// TODO Auto-generated method stub		
	}
	@Override
	public void select() {
		// TODO Auto-generated method stub
	}
}

Proxy.java:代理类

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.lang.reflect.Method;

import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class Proxy {
	public static void main(String[] args) throws Exception {
		Object proxy=newProxyInstance();
		System.out.println(proxy.toString());
	}

	//传进来方法信息(来自接口,也可以来之目标类)
	//类加载器
	//传进来一个invocationHandler的实现类
	public static Object newProxyInstance() throws Exception {//模拟代理对象的创建;
		// 得到方法信息
		Class classInfo = IDAO.class;
		Method[] methods = classInfo.getMethods();
		for (Method method : methods) {
			System.out.println(method.getName());
		}
		// 生成Proxy1.java
		String method1Name = methods[0].getName();
		String method2Name = methods[1].getName();
		//代理类 save(){调用接口InvocationHandler.invoke()}
		String classContent = "public class Proxy1" 
		+ "{public void "+method1Name+"() {} " 
				+ "public void "+method2Name+"(){}"
				+ "}";
		String fileString = "d:\\Proxy1.java";
		FileWriter fileWriter = new FileWriter(fileString);
		fileWriter.write(classContent);
		fileWriter.flush();

		// 编译出Proxy1.class
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
		File file = new File(fileString);
		Iterable units = fileManager.getJavaFileObjects(file);
		CompilationTask task = compiler.getTask(null, fileManager, null, null, null, units);
		task.call();
		// 加载Proxy1.class
		ProxyClasLoader clasLoader=new ProxyClasLoader();
		Class proxyClassInfo=clasLoader.findClass("d:\\Proxy1.class");
		// 创建出代理对象,返回
		Object proxy=proxyClassInfo.newInstance();
		return proxy;

	}
	static class ProxyClasLoader extends ClassLoader{
		@Override
		protected Class<?> findClass(String name) throws ClassNotFoundException {
			try {
				FileInputStream inputStream=new FileInputStream(name);
				int length=inputStream.available();
				byte[] classContent=new byte[length];
				inputStream.read(classContent);
				Class classInfo=defineClass(classContent, 0, classContent.length);
				return classInfo;
			} catch (Exception e) {
				// TODO: handle exception
			}
			return null;
		}
	}

}

其中newProxyInstance方法在实际中由java.lang.reflect.Proxy类中实现创建;

newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

//类加载器,目标类的方法信息;InvocationHandler用来代理方法的调用;//整个过程用来创建代理对象

 

IDAO.java:目标方法实现的接口

public interface IDAO {
	public void save();
	public void select();

}

 

图解思路:

 

推荐阅读