Java学习路线-32:ClassLoader类加载器反射与代理设计模式

简介: Java学习路线-32:ClassLoader类加载器反射与代理设计模式

第25 章 : ClassLoader类加载器

115 ClassLoader类加载器简介

系统环境变量 CLASSPATH

JVM -> ClassLoader -> CLASSPATH -> .class

加载器,由上至下执行

Bootstrap 系统类加载器
PlatformClassLoader 平台类加载器
AppClassLoader 应用程序加载器
自定义类加载器(磁盘、网络)

系统类加载器都是根据CLASSPATH路径查找类加载


应用场景:

客户端动态更新服务器端的代码


Java类加载器:双亲加载机制

为了保证系统安全性,开发者自定义类与系统类重名,不会被加载


/demo/Person.java

public class Person {
    public void sayHello(){
        System.out.println("hello");
    }
}

MyClassLoader.java

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class MyClassLoader extends ClassLoader {
    private static final String PERSON_CLASS_PATH = "/demo" + File.separator + "Person.class";
    public Class<?> loadMyClass(String className) throws IOException {
        byte[] data = this.loadClassData();
        if (data != null) {
            return super.defineClass(className, data, 0, data.length);
        }
        return null;
    }
    public byte[] loadClassData() throws IOException {
        InputStream input = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 将数据加载到内存
        byte[] data = null;
        byte[] temp = new byte[1024];
        int len = 0;
        try {
            input = new FileInputStream(PERSON_CLASS_PATH);
            while ((len = input.read(temp)) != -1) {
                bos.write(temp, 0, len);
            }
            // 读取所有的字节
            data = bos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                input.close();
            }
            if (bos != null) {
                bos.close();
            }
        }
        return data;
    }
}
class Demo {
    public static void main(String[] args) throws Exception{
        MyClassLoader loader = new MyClassLoader();
        Class<?> cls = loader.loadMyClass("Person");
        Object obj = cls.getDeclaredConstructor().newInstance();
        Method method = cls.getDeclaredMethod("sayHello");
        method.invoke(obj);
        // hello
    }
}

第26 章 : 反射与代理设计模式

117 静态代理设计模式

传统代理设计

必须有接口


标准的代理设计

// 接口标准
interface IMessage {
    void send();
}
// 业务实现类
class MessageImpl implements IMessage {
    @Override
    public void send() {
        System.out.println("发送");
    }
}
// 代理类
class MessageProxy implements IMessage {
    private IMessage message;
    public MessageProxy(IMessage message) {
        this.message = message;
    }
    @Override
    public void send() {
        if (this.isConnect()) {
            this.message.send();
        }
    }
    public void close() {
    }
    public boolean isConnect() {
        return true;
    }
}
class Demo {
    public static void main(String[] args) {
        IMessage message = new MessageProxy(new MessageImpl());
        message.send();
    }
}

客户端和接口子类产生了耦合

最好引入工厂设计模式进行代理对象获取


静态代理类:

一个代理类只为一个接口服务

118 动态代理设计模式

最好的做法是为所有功能一致的业务操作接口提供统一的代理处理操作


不管是动态代理类还是静态代理类都一定要接收真实业务实现子类对象


代码实现

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 接口标准
interface IMessage {
    void send();
}
// 业务实现类
class MessageImpl implements IMessage {
    @Override
    public void send() {
        System.out.println("发送");
    }
}
// 动态代理类
class MyProxy implements InvocationHandler{
    private Object target; // 保存真实业务对象
    // 真实业务对象与代理业务对象之间的绑定
    public Object bind(Object target){
        this.target = target;
        Class cls = target.getClass();
        return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object obj = null;
        if (this.isConnect()) {
            obj = method.invoke(this.target, args);
            this.close();
        }
        return obj;
    }
    public void close() {
    }
    public boolean isConnect() {
        return true;
    }
}
class Demo {
    public static void main(String[] args) {
        IMessage message =(IMessage)new MyProxy().bind(new MessageImpl());
        message.send();
    }
}

119 CGLIB实现代理设计模式

如果要实现代理设计模式,那么一定是基于接口的应用

CGLIB开发包实现基于类的代理设计模式

Code Generation Library


pom.xml 引入

<dependencies>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
    </dependency>
</dependencies>

代码实现

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
// 业务实现类
class Message {
    public void send() {
        System.out.println("发送");
    }
}
// 动态代理类
class MyProxy implements MethodInterceptor {
    private Object target; // 保存真实业务对象
    // 真实业务对象与代理业务对象之间的绑定
    public MyProxy(Object target) {
        this.target = target;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object obj = null;
        if (this.isConnect()) {
            obj = method.invoke(this.target, args);
            this.close();
        }
        return obj;
    }
    public void close() {
    }
    public boolean isConnect() {
        return true;
    }
}
class Demo {
    public static void main(String[] args) {
        Message message = new Message(); // 真实主体
        Enhancer enhancer = new Enhancer(); // 负责代理操作的程序类
        enhancer.setSuperclass(message.getClass()); // 假定一个父类
        enhancer.setCallback(new MyProxy(message));
        Message proxyMessage = (Message) enhancer.create();
        proxyMessage.send();
    }
}

建议:基于接口的设计比较合理

相关文章
|
3天前
|
数据采集 人工智能 安全
|
13天前
|
云安全 监控 安全
|
4天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1089 152
|
18天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1754 9
|
9天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
696 152
|
11天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
661 14
|
6天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
446 5