zoukankan      html  css  js  c++  java
  • aop动态代理底层实现模拟

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

    图解思路:

  • 相关阅读:
    永恒之蓝(EternalBlue)MS17-010
    利用msfvenom制作木马程序(你可以得到她的一切)
    远程桌面--------ms12-020 漏洞复现 (死亡蓝屏)
    附近wifi都是你的
    暴力破解加密的压缩文件。
    教你如何暴力破解-telnet ftp ssh mysql mssql vnc 等
    ARP欺骗(完全版)
    世界虽大,但没有破不了的wifi
    关于字符编码的问题。
    toroiseSVN 无法连接服务器,提示unable connect to ……url 参数错误
  • 原文地址:https://www.cnblogs.com/yunianzeng/p/12302113.html
Copyright © 2011-2022 走看看