Java JDK动态代理机制
最近写了一个简单的ORM数据库框架,需要动态实现接口,用到了动态代理,这里记录一下动态代理的实现。
在Java JDK动态代理机制中,最重要的是一个接口(java.lang.reflect.InvocationHandler)和一个类(java.lang.reflect.Proxy)。
jdk动态代理机制有个鲜明的特点:需要代理的类,必须实现某个接口,如果类中出现接口以外的方法,那么产生的动态代理类中是没有该方法的。也就是说,如果某个类没有实现任何接口,那么这个类就不能同JDK产生动态代理。
如想实现动态代理类,请参考cglib 动态代理机制 https://blog.csdn.net/k_young1997/article/details/93187058
1、java.lang.reflect.InvocationHandler 接口
InvocationHandler 接口的源码:
package java.lang.reflect;
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
它定义了一个方法 invoke
其中有三个参数 Object proxy
,Object[] args
,Method method
- Object proxy :所需代理的类的真实对象
- Method method :所需代理的对象中的某个方法的对象
- Object[] args :该方法接收到的参数
invoke 方法用来执行所代理对象中的方法,其返回值类型是 Object ,是因为返回值是所执行方法的返回值。
2、java.lang.reflect.Proxy类
Proxy类最常用的是 `newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)` 静态方法,用该方法可以获得一个动态代理出的对象。
该方法有三个参数:
ClassLoader loader
:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载Class<?>[] interfaces
:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了InvocationHandler h
:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
通过 Proxy.newProxyInstance
创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号。
3、代码演示
在newProxyInstance 方法中需要一个 InvocationHandler 对象,所以先创建一个 InvocationHandler 对象。
package demo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MethodProxy implements InvocationHandler {
private Object obj;
public MethodProxy(Object obj) {
this.obj = obj;
}
//如果你动态代理的是没有实现接口的,以上代码可以省略,下边invoke方法不用执行,
//改为自己想要执行的代码
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法前后都可以加入自己想执行的代码
return method.invoke(obj, args);
}
}
需代理类接口
package demo;
public interface User {
public void hello();
}
需代理类
package demo;
public class UserImpl implements User {
@Override
public void hello() {
System.out.println("Hello Word");
}
}
该类调用 Proxy.newProxyInstance
方法获得一个动态代理的对象
package demo;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
User user = (User) Proxy.newProxyInstance(User.class.getClassLoader(), new Class[] {User.class}, new MethodProxy(new UserImpl()));
user.hello();
}
}
还没有评论,来说两句吧...