java收藏

动态代理反射

2022-02-08  本文已影响0人  go_2021
动态代理

分类
AspectJ编译-静态编译-AspectJ编译编译器
JDK动态代理-接口
cglib动态代理-子类(对ASM的封装)
javassist动态代理-dubbo

JDK动态代理

public interface Subject { 
    String sayHello();
}

public class SubjectImpl implements Subject {  
    @Override
    public String sayHello() {
        System.out.println(" Hello World");
        return "success";
    }
}
//******
public class ProxyInvocationHandler implements InvocationHandler {  
    private Object target;

    public ProxyInvocationHandler(Object target) {
        this.target = target;
    }
//****** 最终还是用的反射调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用处理器 ");
        return method.invoke(target, args);
    }
}
public class ProxyTest {
    public static void main(String[] args) {
        Subject subject = new SubjectImpl();
//******
        Subject proxy = (Subject) Proxy
                .newProxyInstance(
                        subject.getClass().getClassLoader(),
                        subject.getClass().getInterfaces(),
                        new ProxyInvocationHandler(subject));

        proxy.sayHello();
    }
}
public final class $Proxy0 extends Proxy implements Singer {
    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 void perform(String var1) throws  {
        try {
//******  ProxyInvocationHandler.invoke();
            super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }
    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("main.learn.proxy.Singer").getMethod("perform", 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());
        }
    }
}

一些应用

  1. mybatis mapper。
  2. spring aop。
反射

运行时调用类方法,获取类属性,注解等。
比new慢
10亿次慢1s。。

//forName 调用本地方法 上下文切换
Class testUserClass = Class.forName("RefleDemo.TestUser");
    TestUser testUser = (TestUser) testUserClass.newInstance();
//遍历查找方法,找不到还会找父类
    Method method = testUserClass.getMethod("sayHi");
    int i = 0;
    while(i<100000000){
        ++i;
    //关闭检查提高效率  开启非public调用
        method.setAccessible(true);
        method.invoke(testUser);
    }
上一篇下一篇

猜你喜欢

热点阅读