jdk的动态代理:
注意jdk的动态代理要求被代理的类必须实现了接口,我们先定义被代理的主类MyServer:
public interface Server {
void print();
}
public class MyServer implements Server {
public void print() {
System.out.println("Myserver call");
}
}
首先,我们需要定义一个handler来对调用进行处理,需要实现InvocationHandler:
public class JHandler implements InvocationHandler{
MyServer server; //handler中必须封装被代理的对象
public JHandler( MyServer server) {
this.server = server;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JHandler call");
return method.invoke(server,args); //通过反射,调用原方法
}
}
这样我们在代码中就可以先给Myserver对象生成一个代理类,然后在调用代理类的print方法:
public class TestProxy {
public static void main(String[] args) {
MyServer server = new MyServer(); //这个是被代理的实际对象
//这里生成一个MyServer的代理对象,注意必须是父接口Server类型,所以JDK的动态代理只能代理父接口中有的方法
Server pServer = (Server) Proxy.newProxyInstance(server.getClass().getClassLoader(),
server.getClass().getInterfaces(), new JHandler(server));
//这样我们就可以调用代理类来处理了
pServer.print();
}
}
当然,输出结果是:
JHandler call
Myserver call
源码分析:
上面说了基本用法,那么jdk是怎么实现这个功能的呢?我们进入newProxyInstance方法:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) {
Objects.requireNonNull(h);
final Class<?> caller = System.getSecurityManager() == null
? null
: Reflection.getCallerClass();
/*
* Look up or generate the designated proxy class and its constructor.
*/
Constructor<?> cons = getProxyConstructor(caller, loader, interfaces); //生成代理类并获取它的构造器
return newProxyInstance(caller, cons, h);
}
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
* Look up or generate the designated proxy class.
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
return cons.newInstance(new Object[]{h});
}
可以看出主要就是三步:生成代理类的class对象-获取代理类的构造函数-实例化代理对象
主要就是生成代理类,当然,都有classloader和interface了,生成一个类不是很简单。那具体怎么生成的呢?大概就是有一个Factory,将classLoader和interface作为参数传给它,它会给你生成一个class对象,生成的代理类会被放在一个cache里。具体的我也不知道,因为看不下去了==、
cglib动态代理
jdk的动态代理是在运行时创建了一个接口的实现类来实现的,而cglib在运行时创建的代理对象是针对目标类扩展的子类
网友评论