JDK 动态代理 基于接口的代理,基于java.lang.reflect.Proxy
接口
public interface ILoginService {
void login(String userName,String password);
}
实现类
public class LoginService implements ILoginService {
@Override
public void login(String userName, String password) {
System.out.println("姓名:"+userName+",密码:"+password+ " 登陆成功!...");
}
}
代理
public class ProxyTest {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//可以输出 $Proxy0.class
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
//第一步 获取Proxy代理对象
Class<?> proxyClass = Proxy.getProxyClass(ProxyTest.class.getClassLoader(), ILoginService.class);
//第二步 获取构造方法,及其参数
System.out.println("----------begin constructors list----------");
//输出 com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler)
// 构造函数名称:com.sun.proxy.$Proxy0
// 构造函数参数:java.lang.reflect.InvocationHandler
Constructor<?>[] constructors = proxyClass.getConstructors();
for (Constructor<?> constructor : constructors) {
//获取构造方法名称
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
// 获取构造函数中的 参数
Class<?>[] types = constructor.getParameterTypes();
for (Class<?> type : types) {
sBuilder.append(type.getName()).append(',');
}
if (types != null && types.length > 0) {
sBuilder.deleteCharAt(sBuilder.length() - 1);
}
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
//第三步 获取成员方法,及其参数
System.out.println("----------begin methods list----------");
Method[] methods = proxyClass.getDeclaredMethods();
for (Method method : methods) {
//获取 成员方法 名称
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
// 获取 成员方法 参数
Class<?>[] types = method.getParameterTypes();
for (Class<?> type : types) {
sBuilder.append(type.getName()).append(',');
}
if (types != null && types.length > 0) {
sBuilder.deleteCharAt(sBuilder.length() - 1);
}
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
// 第四步 获取实例
System.out.println("----------begin create instance object----------");
//输出 com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler)
// 构造函数名称:com.sun.proxy.$Proxy0
// 构造函数参数:java.lang.reflect.InvocationHandler
Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
class MyInvocationHandler implements InvocationHandler {
//直接在InvocationHandler实现类中创建目标类的实例对象,但没有实际意义
ILoginService target= new LoginService();
/**
*
* @param proxy 目标代理对象
* @param method 执行目标代理方法
* @param args 代理实例上的方法调用中传递的参数值的对象数组
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("methodName="+method.getName());
return method.invoke(target,args);
}
}
ILoginService proxy1 = (ILoginService) constructor.newInstance(new MyInvocationHandler());
//没有报空指针异常,说明toString() 方法返回为 null
System.out.println("------" + proxy1.toString()); // 当 invoke() return 为null 时,输出 null
proxy1.login("lisi","123456");
System.out.println("/**---------------------------------------------------------------------------------------------*/");
ILoginService proxy2 = (ILoginService) Proxy.newProxyInstance(ProxyTest.class.getClassLoader(), LoginService.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ILoginService target = new LoginService();
System.out.println("代理前操作....");
Object invoke = method.invoke(target, args);
System.out.println("代理后操作....");
return invoke;
}
});
proxy2.login("zhangsan","123456");
}
}
输出结果:
----------begin constructors list----------
com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler)
----------begin methods list----------
equals(java.lang.Object)
toString()
hashCode()
login(java.lang.String,java.lang.String)
----------begin create instance object----------
methodName=toString
------com.hapzxb.service.impl.LoginService@29453f44
methodName=login
姓名:lisi,密码:123456 登陆成功!..
/**---------------------------------------------------------------------------------------------*/
代理前操作…
姓名:zhangsan,密码:123456 登陆成功!..
代理后操作…
$Proxy.class 反编译
package com.sun.proxy;
import com.hapzxb.service.ILoginService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements ILoginService {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void login(String var1, String var2) throws {
try {
super.h.invoke(this, m3, new Object[]{var1, var2});
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.hapzxb.service.ILoginService").getMethod("login", Class.forName("java.lang.String"), Class.forName("java.lang.String"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}