反射

动态构建,操作类的一种手段,重要!
比如,bean的加载,初始化。销毁,就是用反射实现

https://blog.csdn.net/weixin_42724467/article/details/84311385?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

helloword 反射调用实例

  1. Class<?> aClass = Class.forName("security.Children",false, ClassUtils.getDefaultClassLoader());
  2. Method helloword = aClass.getDeclaredMethod("helloword",null);
  3. System.out.println(helloword);
  4. helloword.invoke(aClass.newInstance(),null); // 调用成员无参数方法
  5. Method main = aClass.getDeclaredMethod("main",String[].class);
  6. System.out.println(main);
  7. main.invoke(null,new Object[]{new String[]{}}); // 调用静态有参数方法

动态代理

jdk动态代理,,只能代理接口 Proxy.newProxyInstance 只能强转成接口类型
下面的demo会报错,强转类型改成接口OK

demo

代理类

  1. public class InvocetionHandler implements InvocationHandler {
  2. private Object target;
  3. public void setTarget(Object target)
  4. {
  5. this.target = target;
  6. }
  7. @Override
  8. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  9. System.out.println("befpre");
  10. Object invoke = method.invoke(target, args);
  11. System.out.println("after");
  12. return invoke;
  13. }
  14. // 生成代理类
  15. public Object CreatProxyedObj()
  16. {
  17. return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
  18. }
  19. }

功能类

  1. public class HelloImpl implements Hello{
  2. @Override
  3. public String sayHello() {
  4. System.out.println("hello");
  5. return "hello";
  6. }
  7. public String sayHello1() {
  8. System.out.println("hello1");
  9. return "hello";
  10. }
  11. }

功能接口

  1. public interface Hello {
  2. String sayHello();
  3. }

源码

重点在 Proxy.newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h) 方法

image.png

这个方法返回代理类,如果不存在就新建一个,核心方法

image.png

proxyClassCache 是缓存的重要结构,后面介绍

image.png

KeyFactory 简单工厂,实现函数式接口就是根据接口长度实现包装

image.png

就看 key1 实现key的弱引用

image.png

重点1 ProxyClassFactory 就是这里动态生成了代理类,后面用到再看

image.png

先了解几个变量

image.png

开始看get方法

image.png
image.png
image.png

重点2:

看上面的get方法

image.png
image.png
image.png
image.png

此时已经拿到了代理类

image.png
image.png

结束

image.png

调用接口方法会直接调用 h的invoke方法
怎么实现的??
理论上可以代理任何接口,像这样
是不是有点注入的味道?

  1. Class<?>[] a = {Hello.class,Pole.class};
  2. Class<?> helloImpl = Class.forName("entry.HelloImpl");
  3. // 用默认的类加载器
  4. Object o1 = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), a, new InvocationHandler() {
  5. @Override
  6. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  7. return method.invoke(BeanUtils.instantiateClass(helloImpl), args);
  8. }
  9. });
  10. ((Hello) o1).sayHello();
  11. ((Pole) o1).syaBey();