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();
    }
}

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

相关文章
|
27天前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
18 0
[Java]反射
|
27天前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
44 0
[Java]23种设计模式
|
10天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
1月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
26 2
|
1月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
1月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
16 0
|
1月前
|
设计模式 Java
Java设计模式
Java设计模式
28 0
|
1月前
|
设计模式 Java
Java设计模式之外观模式
这篇文章详细解释了Java设计模式之外观模式的原理及其应用场景,并通过具体代码示例展示了如何通过外观模式简化子系统的使用。
29 0
|
1月前
|
设计模式 Java
Java设计模式之桥接模式
这篇文章介绍了Java设计模式中的桥接模式,包括桥接模式的目的、实现方式,并通过具体代码示例展示了如何分离抽象与实现,使得两者可以独立变化。
44 0
|
存储 SQL Java
Java反射读取注解信息
Java反射读取注解信息
70 0
下一篇
无影云桌面