前一篇文章
我们分析了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的帮凶(子类),并动态实现委托接口,充当代码生成器的凶手。
分享到:
相关推荐
总结起来,Java动态代理提供了一种在运行时创建代理对象的机制,通过 `Proxy` 类和 `InvocationHandler` 接口,我们可以灵活地在方法调用前后插入自定义的行为,实现诸如日志、事务等附加功能,极大地增强了代码的可...
Java 动态代理机制是Java反射API的一部分,它允许我们在运行时创建代理类,这些代理类可以实现我们指定的一组接口。动态代理的核心是`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。 1....
首先,我们需要了解Java中的两种动态代理机制:JDK动态代理和CGLIB动态代理。JDK动态代理基于接口实现,适用于目标对象实现了接口的情况;而CGLIB则是通过字节码技术,可以在无接口的情况下生成目标类的子类,实现对...
本文通过分析Java动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java动态代理运作过程,希望能帮助读者加深对Java动态代理的理解和应用。本文的标签...
3. **Final类的问题**:由于CGLIB是基于继承机制实现的,因此无法对声明为`final`的类进行代理,因为Java不支持子类化`final`类。 **CGLIB的使用步骤:** 1. **引入依赖**:在项目中添加CGLIB的依赖,通常通过Maven...
Java动态代理是Java提供的一种在运行时创建代理对象的技术,它是实现类似Spring AOP(面向切面编程)功能的关键机制之一。AOP允许我们在不修改已有代码的情况下,向程序添加额外的功能,比如日志记录、性能监控、...
通过模拟其内部实现,我们可以更深入地理解动态代理的工作原理,并根据需求定制自己的代理机制。通过阅读和分析提供的代码文件(3-1代码、3-2代码、3-3代码),我们可以看到具体的实现细节,如方法的调用链路、参数...
Java动态代理主要由`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`接口组成,它们提供了一种机制,可以在运行时创建一个实现了特定接口的新类,这个新类的实例可以作为这些接口的代理,以处理...
1. **`java.lang.reflect.Proxy` 类**:通过 Proxy 类,我们可以创建一个代理类实例,该实例动态实现指定的接口,调用接口方法时,可以通过代理类调用 `InvocationHandler` 的 `invoke` 方法添加额外的行为。...
总结,Java的动态代理机制结合反射API,为我们提供了强大的代码生成和运行时行为调整能力。通过理解并熟练运用这些概念,开发者可以构建出更灵活、可扩展的系统。在"ReflectProxyDemo"这个实例中,我们可以亲身体验...
Java动态代理机制是一种在运行时创建代理类的技术,它允许我们为已有接口创建代理对象,以便在不修改原代码的情况下,扩展或增强原有对象的功能。动态代理主要涉及到两个核心概念:`InvocationHandler` 和 `Proxy`。...
在本篇中,我们将深入探讨如何使用Java动态代理来实现Xutils的注入模块。Xutils是一个知名的Android开发框架,它提供了包括网络请求、数据库操作、图片加载等多种功能,而注入机制则是提高代码可读性和可维护性的...
Java动态代理机制允许在运行时创建一个接口的实现类,这个实现类可以代理原始的目标对象。它主要由两个类组成:`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`。Proxy类用于创建代理对象,而...
Java动态代理机制允许我们在运行时创建一个新的类,该类实现了特定接口,并能代理接口方法的调用。这主要通过`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个类实现。 1. **Proxy类**:`...
JDK动态代理是Java标准库中提供的一种机制,位于`java.lang.reflect`包下。它通过实现`java.lang.reflect.InvocationHandler`接口并使用`java.lang.reflect.Proxy`类来创建代理对象。`InvocationHandler`接口定义了...
Java提供了两种动态代理机制:基于接口的JDK动态代理和基于类的CGLIB动态代理。本案例主要关注基于接口的JDK动态代理。 #### 三、JDK动态代理的关键步骤 1. **定义接口**: - 首先定义一个接口`Speak`,它规定了...
5. **工具应用**:在实际开发中,Java动态代理常被用作AOP(面向切面编程)的一种实现方式,例如Spring框架中的JDK动态代理。此外,还可以用于事件监听、缓存、日志记录等场景。 总结来说,Java动态代理提供了一种...