类的加载_双亲委派_动态代理

一:类的加载

1. 类加载的阶段

2. ClassLoader 继承关系

PathClassLoader  --- 应用的类(自己写类/jar包里的/第三方库如Guilde)
BootClassLoader  --- SDK的类(比如:Activity的类加载器就是BootClassLoader)

3. 类的加载机制

4.类的加载机制(时序图)

5. dex 文件的生成命令

二:双亲委派

1. 定义:什么是双亲委派?

某个类加载器在加载类时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务或者没有父类加载器时,才自己去加载。

2. 底层实现

3. 为什么要双亲委派机制?意义是啥?

1、避免重复加载,当父加载器已经加载了该类的时候,就没有必要子ClassLoader再加载一次。 2、安全性考虑,防止核心API库被随意篡改。

三:动态代理

1.举例说明动态代理是咋回事

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class DynamicProxyExample {
 
    // 被代理的接口
    interface Subject {
        void doSomething();
    }
 
    // 被代理的实际类
    static class RealSubject implements Subject {
        @Override
        public void doSomething() {
            System.out.println("RealSubject.doSomething()");
        }
    }
 
    // 动态代理处理器
    static class DynamicProxyHandler implements InvocationHandler {
        private Object originalObject;
 
        public DynamicProxyHandler(Object originalObject) {
            this.originalObject = originalObject;
        }
 
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Before method invocation: " + method.getName());
            Object result = method.invoke(originalObject, args);
            System.out.println("After method invocation: " + method.getName());
            return result;
        }
    }
 
    public static void main(String[] args) {
        // 创建实际的被代理对象
        Subject realSubject = new RealSubject();
 
        // 创建动态代理
        Subject proxySubject = (Subject) Proxy.newProxyInstance(
                Subject.class.getClassLoader(), // 类加载器
                new Class<?>[]{Subject.class},   // 代理类需要实现的接口
                new DynamicProxyHandler(realSubject) // 代理处理器
        );
 
        // 调用代理对象的方法,实际上会被DynamicProxyHandler拦截
        proxySubject.doSomething();
    }
}

RealSubject 是被代理的对象,

DynamicProxyHandler 实现了 InvocationHandler 接口,用于拦截方法调用。

通过 Proxy.newProxyInstance 方法,我们创建了一个代理实例 proxySubject,它将所有方法调用委托给 DynamicProxyHandler,在调用实际的 RealSubject 方法之前和之后,可以进行一些额外的处理,比如日志记录、性能分析等。

2. 静态代理

目标类和代理类实现了相同的接口,在代理类中依赖了目标类,代理类的方法中调用了目标类的方法,并做了一些增强性的工作。

举例:实现一个功能,要求:在某个类,执行类中的方法时,上下文添加一些日志记录

静态代理的缺陷

  • 程序员要手动为每一个目标类编写对应的代理类。如果当前系统已经有成百上千个类,工作量太大了
  • 当接口改变时,所有的代理类都需要进行相应的变化,太过于耦合
    所以,现在我们的努力方向是:如何少写或者不写代理类,却能完成代理功能?

3. 定义:什么是动态代理?

指的是:在程序的执行过程中,使用jdk的反射机制,创建代理对象,并动态的指定代理的目标类

动态代理的实现方式常用有两种:
- 使用JDK代理
- 通过CDLIB代理

使用JDK代理

jdk动态代理是基于Java的反射机制实现的,使用jdk反射包下的Proxy和InvocationHandler实现代理对象的动态创建。(jdk动态代理要求目标对象必须实现接口)

1)InvocationHandler接口

方法拦截处理器,接口中就一个方法 :invoke(),你的代理类要完成的功能就写在invoke()中

  • 调用目标类的方法
  • 功能增强,在目标方法调用时,增加功能

2)Method类

通过Method可以执行某个目标类的方法

3)proxy类

是最核心的一个类,使用静态方法 newProxyInstance() ,创建代理对象
方法原型:

4)动态代理的实现步骤

   1)创建接口,定义目标类要完成的功能

  2)  创建目标类,实现该接口

 3)  创建 InvocationHandler 接口的实现类,在invoke()方法中完成代理类的功能

 4) 使用proxy类的newProxyInstance()方法,创建代理对象,并把返回值转成接口类型

5. jdk动态代理的执行流程

断点打到InvocationHandler的invoke方法中,查看method和args参数,可以看到 method 是add, args 是int,int

Proxy.newProxyInstance() 返回的对象,就是jdk创建的一个代理对象, 这里返回的是Calculate类型

6. 动态代理能做什么?

在不改变原来目标方法功能的前提下,可以在代理中增强自己功能代码。

在程序开发中的意义:
- 你所在的项目中,有一个功能是其他人写好的,你可以使用,但是不能满足我的需求,我需要再增加点代码,这次就需要使用代理来进行代码的增强,而不用改原来的代码

  • 30
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值