您当前的位置: 首页 >  Java

彭世瑜

暂无认证

  • 0浏览

    0关注

    2791博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

彭世瑜 发布时间:2019-12-31 22:49:25 ,浏览量:0

第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 引入


    
        cglib
        cglib
        2.2.2
    

代码实现

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

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

关注
打赏
1665367115
查看更多评论
立即登录/注册

微信扫码登录

0.3053s