`
niuzai
  • 浏览: 68122 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

模拟实现Java动态代理机制

阅读更多

  前一篇文章 我们分析了Java Proxy动态代理类,只是从表面知道他就是打着他人的旗帜,干着自己的勾当! 但是本质上还没有搞清楚它的非法运营模式,这一章我们就来模拟一下犯罪现场,以及解决前一章遗留的问题。模拟开始先~

 

    一、定义委托高层接口

 

/**
 * 模拟Java动态代理机制
 */
package com.demo.delegator;

/**
 * 定义委托高层接口
 * @author Andy
 * @since 2012.02.17 15:59 PM
 * @version 1.0
 *
 */
public final class IDelegator {

	/**
	 * 接口一
	 *
	 */
	public static interface One{
		public void sing();
	}
	
	/**
	 * 接口二
	 *
	 */
	public static interface Two{
		public int write();
	}
	
	/**
	 * 接口三
	 * 
	 */
	public static interface Three{
		public String read();
	}
}

 

    二、定义委托实现类

 

/**
 * 模拟java动态代理机制
 */
package com.demo.delegator.impl;

import com.demo.delegator.IDelegator;

/**
 * 委托实现类
 * 
 * @author Andy
 * @see	com.demo.delegator.IDelegator.One
 * @see	com.demo.delegator.IDelegator.Two
 * @see	com.demo.delegator.IDelegator.Three
 * @since 2012.02.17 15:59 PM
 * @version 1.0
 */
public class DelegatorImpl implements IDelegator.One , IDelegator.Two , IDelegator.Three {

	@Override
	public String read() {
		this.print();
		return "";
	}

	@Override
	public int write() {
		this.print();
		return 0;
	}

	@Override
	public void sing() {
		this.print();
	}

	private void print(){
		String message = "Invoke " + Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName();
		System.out.println(message);
	}
}

 

       三、定义代理类

 

 

/**
 * 模拟Java动态代理机制
 */
package com.demo.proxy;

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

import com.demo.delegator.IDelegator;

/**
 * 模拟JAVA动态代理类
 * 
 * 
 * JAVA原生动态代理类由ProxyGenerator动态生成实现代理接口的字节码,并注入classloader中。
 * 参见源码:
 * String proxyName = proxyPkg + "$proxy" + num;
 * byte[] proxyClassFile =	ProxyGenerator.generateProxyClass(proxyName, interfaces);
 * proxyClass = defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
 * 
 * 代理机制:
 * 代理类和委托代理类都实现了代理接口,当代理类调用代理接口时,首先会触发调用处理程序。
 * 再由处理程序分发调用委托代理类的接口。从而实现了代理类对委托代理类的隔离。
 * 
 * @author Andy
 * @see	com.demo.delegator.IDelegator.One
 * @see	com.demo.delegator.IDelegator.Two
 * @see	com.demo.delegator.IDelegator.Three
 * @since 2012.02.17 15:59 PM
 * @version 1.0
 */
public final class DynamicProxy implements IDelegator.One , IDelegator.Two , IDelegator.Three {

	// 引用调用处理对象
	private static InvocationHandler handler;
	private static Class<?>[] interfaces = null;
        private static Map<Class<?>, DynamicProxy> cachMap = Collections.synchronizedMap(new HashMap<Class<?> , DynamicProxy>());

        private DynamicProxy(Class<?>[] interfaces , InvocationHandler handler){
		DynamicProxy.handler = handler;
		DynamicProxy.interfaces = interfaces;
	}
	
	public static Object newInstance(Class<?> clazz, Class<?>[] interfaces,InvocationHandler handler){
		DynamicProxy proxy = cachMap.get(clazz);
		if(null == proxy){
			proxy = new DynamicProxy(interfaces , handler);
			cachMap.put(clazz, proxy);
		}
		return proxy;
	}

	@Override
	public String read() {
		return String.valueOf(this.invoke());
	}

	@Override
	public int write() {
		return Integer.valueOf(this.invoke().toString());
	}

	@Override
	public void sing() {
		this.invoke();
	}
	
	
	private Object invoke(){
		Object obj = null;
		try {
			StackTraceElement[] elements = Thread.currentThread().getStackTrace();
			String methodName = elements[2].getMethodName();
			
			for (int i = 0; i < interfaces.length; i++) {
				Class<?> clazz = interfaces[i];
				Method[] methods = clazz.getMethods();
				for (int j = 0; j < methods.length; j++) {
					Method method = methods[j];
					if(methodName.equals(method.getName())){
						Class<?> args[] = method.getParameterTypes();
						obj = handler.invoke(this, method, args);
						break;
					}
				}
			}
			
			return obj;
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
}

 

   四、定义委托调用处理程序

 

/**
 * 
 */
package com.demo.proxy;

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

/**
 * 委托接口调用处理程序
 * 
 * @author Andy
 * @see	java.lang.reflect.InvocationHandler
 * @since 2012.02.17 15:59 PM
 * @version 1.0
 */
public class AOPHandler implements InvocationHandler {

	private Object instance = null;
	
	private AOPHandler(Class<?> clazz){
		try {
			this.instance = clazz.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static Object getProxyInstance(Class<?> clazz , Class<?> interfaces[]){
		return DynamicProxy.newInstance(clazz , interfaces , new AOPHandler(clazz));
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println(method.getName() + " invoke start.");
		Object returnValue = method.invoke(this.instance, args);
		System.out.println(method.getName() + " invoke end.");
		return returnValue;
	}
}
 

 

   五、模拟代理测试类

 

/**
 * 模拟Java动态代理机制
 */
package com.demo;

import com.demo.delegator.IDelegator;
import com.demo.delegator.impl.DelegatorImpl;
import com.demo.proxy.AOPHandler;

/**
 * 代理测试类
 * @author Andy
 *
 */
public class ProxyTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 创建调用处理程序
		IDelegator.One proxy = (IDelegator.One)AOPHandler.getProxyInstance(DelegatorImpl.class , DelegatorImpl.class.getInterfaces());
		proxy.sing();
	}
}
 

 

   总结:委托类与代理类都实现了委托高层接口,故代理类可以处理委托类的请求。当代理类拦截到接口请求时,首先进行委托调用处理程序(所谓的拦截器),在委托调用处理程序中才真正决定是否分发委托类的请求。代理就这样轻松的实现了委托授权,隔离委托类的直接调用。

   分析了代理的机制,上一章ProxyGenerator.generateProxyClass(String s, Class clazz[])也不再是个谜。不难推测它就是Proxy的帮凶(子类),并动态实现委托接口,充当代码生成器的凶手。

 

 

1
0
分享到:
评论

相关推荐

    java动态代理模拟实现

    总结起来,Java动态代理提供了一种在运行时创建代理对象的机制,通过 `Proxy` 类和 `InvocationHandler` 接口,我们可以灵活地在方法调用前后插入自定义的行为,实现诸如日志、事务等附加功能,极大地增强了代码的可...

    JAVA 动态代理机制

    Java 动态代理机制是Java反射API的一部分,它允许我们在运行时创建代理类,这些代理类可以实现我们指定的一组接口。动态代理的核心是`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。 1....

    个人用java动态代理模拟实现spring aop

    首先,我们需要了解Java中的两种动态代理机制:JDK动态代理和CGLIB动态代理。JDK动态代理基于接口实现,适用于目标对象实现了接口的情况;而CGLIB则是通过字节码技术,可以在无接口的情况下生成目标类的子类,实现对...

    Java动态代理机制分析及扩展

    本文通过分析Java动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java动态代理运作过程,希望能帮助读者加深对Java动态代理的理解和应用。本文的标签...

    Java动态代理资源包

    3. **Final类的问题**:由于CGLIB是基于继承机制实现的,因此无法对声明为`final`的类进行代理,因为Java不支持子类化`final`类。 **CGLIB的使用步骤:** 1. **引入依赖**:在项目中添加CGLIB的依赖,通常通过Maven...

    java 动态代理实现,模拟spring aop

    Java动态代理是Java提供的一种在运行时创建代理对象的技术,它是实现类似Spring AOP(面向切面编程)功能的关键机制之一。AOP允许我们在不修改已有代码的情况下,向程序添加额外的功能,比如日志记录、性能监控、...

    模拟JDK动态代理内部实现

    通过模拟其内部实现,我们可以更深入地理解动态代理的工作原理,并根据需求定制自己的代理机制。通过阅读和分析提供的代码文件(3-1代码、3-2代码、3-3代码),我们可以看到具体的实现细节,如方法的调用链路、参数...

    java反射与动态代理笔记

    Java动态代理主要由`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`接口组成,它们提供了一种机制,可以在运行时创建一个实现了特定接口的新类,这个新类的实例可以作为这些接口的代理,以处理...

    java 反射机制与动态代理

    1. **`java.lang.reflect.Proxy` 类**:通过 Proxy 类,我们可以创建一个代理类实例,该实例动态实现指定的接口,调用接口方法时,可以通过代理类调用 `InvocationHandler` 的 `invoke` 方法添加额外的行为。...

    Java动态代理ReflectProxyDemo

    总结,Java的动态代理机制结合反射API,为我们提供了强大的代码生成和运行时行为调整能力。通过理解并熟练运用这些概念,开发者可以构建出更灵活、可扩展的系统。在"ReflectProxyDemo"这个实例中,我们可以亲身体验...

    java动态代理1

    Java动态代理机制是一种在运行时创建代理类的技术,它允许我们为已有接口创建代理对象,以便在不修改原代码的情况下,扩展或增强原有对象的功能。动态代理主要涉及到两个核心概念:`InvocationHandler` 和 `Proxy`。...

    Java动态代理运用之实现Xutils注入模块

    在本篇中,我们将深入探讨如何使用Java动态代理来实现Xutils的注入模块。Xutils是一个知名的Android开发框架,它提供了包括网络请求、数据库操作、图片加载等多种功能,而注入机制则是提高代码可读性和可维护性的...

    深度理解,自己实现java动态代理、自动注入、切面编程(类似于Spring IOC、AOP)

    Java动态代理机制允许在运行时创建一个接口的实现类,这个实现类可以代理原始的目标对象。它主要由两个类组成:`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`。Proxy类用于创建代理对象,而...

    经典java反射和动态代理代码

    Java动态代理机制允许我们在运行时创建一个新的类,该类实现了特定接口,并能代理接口方法的调用。这主要通过`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个类实现。 1. **Proxy类**:`...

    java dtdl 动态代理

    JDK动态代理是Java标准库中提供的一种机制,位于`java.lang.reflect`包下。它通过实现`java.lang.reflect.InvocationHandler`接口并使用`java.lang.reflect.Proxy`类来创建代理对象。`InvocationHandler`接口定义了...

    java的动态代理

    Java提供了两种动态代理机制:基于接口的JDK动态代理和基于类的CGLIB动态代理。本案例主要关注基于接口的JDK动态代理。 #### 三、JDK动态代理的关键步骤 1. **定义接口**: - 首先定义一个接口`Speak`,它规定了...

    java动态代理总结(狗星例子)

    5. **工具应用**:在实际开发中,Java动态代理常被用作AOP(面向切面编程)的一种实现方式,例如Spring框架中的JDK动态代理。此外,还可以用于事件监听、缓存、日志记录等场景。 总结来说,Java动态代理提供了一种...

Global site tag (gtag.js) - Google Analytics