java中动态代理代码解析
2020-05-30 本文已影响0人
ModestStorm
接口类IPerson
public interface IPerson {
void setSex(int sex) throws Throwable;
int getSex() throws Throwable;
}
具体实现类Man
public class Man implements IPerson {
private int sex;
@Override
public void setSex(int sex) {
this.sex = sex;
}
@Override
public int getSex() {
return sex;
}
@NonNull
@Override
public String toString() {
return "hello";
}
}
动态代理类生成
@Test
public void testDynamic() throws Throwable {
Man man=new Man();
man.setSex(10);
IPerson proxyPerson= (IPerson) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{IPerson.class},new CustomInvocationHandler(man));
// proxyPerson.setSex(12);
System.out.print("man sex=" + proxyPerson.getSex());
}
private class CustomInvocationHandler implements InvocationHandler {
IPerson target;
public CustomInvocationHandler(IPerson target){
this.target=target;
}
/*
* 参数proxy:动态代理对象$proxy0的实例,不是man的示例,网上有些博客写错了
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(">>>> before:"+method.getName());
if(args!=null){
for (Object arg : args) {
System.out.println("args:"+arg);
}
}
Object result=method.invoke(target,args);
//动态修改原值
if(result instanceof Integer){
result=((Integer) result).intValue()+1;
}
System.out.println(">>> end success");
return result;
}
}
}
反编译查看最终生成的代理类$Proxy0,可以理解动态代理类内部实现逻辑
public class $Proxy0 extends Proxy implements IPerson{
private InvocationHandler handler;
private static Method m0;
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m4;
static {
try {
m0= Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m1 = Class.forName("java.lang.Object").getMethod("toString");
m2= Class.forName("java.lang.Object").getMethod("hashCode");
m3 = Class.forName("proxy.Person").getMethod("getSex");
m4 = Class.forName("proxy.Person").getMethod("setSex", Integer.class);
}catch (Exception e){
e.printStackTrace();
}
}
protected $Proxy0(@NonNull InvocationHandler h) {
super(h);
this.handler=h;
}
/*
* equals,hashCode方法是一样的道理
*/
@NonNull
@Override
public String toString() {
try {
return (String) handler.invoke(this,m1,null);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return super.toString();
}
@Override
public void setSex(int sex) throws Throwable {
handler.invoke(this,m4,new Object[]{sex});
}
@Override
public int getSex() throws Throwable {
return (int) handler.invoke(this,m3,null);
}
}