首页 > 其他分享 >通过反射加载内部或者外部class对象

通过反射加载内部或者外部class对象

时间:2022-10-03 11:11:54浏览次数:47  
标签:反射 handlerConfig String private import class 加载

一、class对象信息

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.Data;

/**
 * handler的配置信息
 */
@Data
public class HandlerConfig {

    /**
     * 处理类版本
     */
    private String handlerVersion;

    /**
     * 处理类类名
     */
    private String handlerClassName;

    /**
     * 处理类包名
     */
    private String handlerPackage;

    /**
     * class文件存儲地址
     */
    private String filePath;


    /**
     * class文件存储名称
     */
    private String fileName;

    /**
     * 是否从外部加载 true:从外部加载 false:本地加载
     */
    private boolean isInitialized = false;

 }

二、创建本地class读取器

import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 本地class加载器
 */
@Slf4j
public class LocalClassLoader extends ClassLoader {

    /**
     * 读取 jar包外的 Class文件,获取到 bean
     *
     * @param fileAddress class文件绝对路径
     * @param className   class文件的package+类名
     * @return Class<?>
     */
    public Class<?> findClass(String fileAddress, String className) {
        String[] split = className.split("\\.");
        File file = new File(fileAddress + split[split.length - 2] + ".class");
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int len;
            while ((len = fileInputStream.read()) != -1) {
                byteArrayOutputStream.write(len);
            }
            byte[] data = byteArrayOutputStream.toByteArray();
            fileInputStream.close();
            byteArrayOutputStream.close();
            String classN = className.substring(0, className.lastIndexOf("."));
            return defineClass(classN, data, 0, data.length);
        } catch (IOException e) {
            log.error("读取jar包外class文件出现异常!【{}】", e.getMessage());
        }
        return null;
    }
}

三、创建工具类

BaseHandler做为统一的父类对象使用,可根据自己需要进行返回值修改

import com.alibaba.fastjson.JSON;
import com.ft.monitoring.dataInterface.common.base.BaseHandler;
import com.ft.monitoring.dataInterface.common.base.HandlerConfig;
import lombok.extern.slf4j.Slf4j;

/**
 * 通过反射创建对象
 *
 */
@Slf4j
public class ObjectContainer {
    /**
     * jar包class加载器
     */
    private static final ClassLoader loader = ObjectContainer.class.getClassLoader();
    /**
     * 本地加载器
     */
    private static final LocalClassLoader localLoader = new LocalClassLoader();

    /**
     * 获取基础处理类
     *
     * @param handlerConfig handler配置类
     * @return
     */
    public static BaseHandler getBaseHandler(HandlerConfig handlerConfig) {
        BaseHandler baseHandler = null;
        if (handlerConfig.isInitialized()) {
            //获取本地文件路径
            try {
                baseHandler = (BaseHandler) localLoader.findClass(handlerConfig.getFilePath(),
                        handlerConfig.getFilePath() + "." + handlerConfig.getFileName()).newInstance();
            } catch (Exception e) {
                log.error("加载本地class失败:" + JSON.toJSONString(handlerConfig), e.getMessage());
            }
        } else {
            try {
                baseHandler = (BaseHandler) loader.loadClass(handlerConfig.getHandlerPackage() + "." + handlerConfig.getHandlerClassName()).newInstance();
            } catch (Exception e) {
                log.error("加载Jar包内class失败:" + JSON.toJSONString(handlerConfig), e.getMessage());
            }
        }
        return baseHandler;
    }


}

四、使用

 public void createHandler(){
        HandlerConfig handlerConfig = new HandlerConfig();
        //加载jar内部class
        handlerConfig.setHandlerPackage("cn.com.demo");
        handlerConfig.setHandlerClassName("Test");
        handlerConfig.setHandlerVersion("v1.0");
        handlerConfig.setInitialized(false);
        //加载外部class
        handlerConfig.setFilePath("D://cn//com//demo");
        handlerConfig.setFileName("Test.class");
        handlerConfig.setInitialized(true);
        //实例化handler对象
        BaseHandler baseHandler = ObjectContainer.getBaseHandler(handlerConfig);
    }

 

标签:反射,handlerConfig,String,private,import,class,加载
From: https://www.cnblogs.com/Sora-L/p/16750173.html

相关文章

  • 【反射】反射基本使用
    1.获取类信息classStudent{static{System.out.println("加载Student类");}publicStudent(){System.out.println("ConstructStud......
  • class 4 笔记
    intsum(intv,inttl,inttr,intl,intr){   if(r<tl||tr<l)       return0;   if(l<=tl&&tr<=r){       returnt[v];......
  • LIME模型---"Why Should I Trust You?": Explaining the Predictions of Any Classifi
    文章核心思想速读:提出了一个LIME解释技术能够对任何分类器做出的预测进行解释。L指LOCAL,意思是模型是针对局部某个样本的解释,而不是所有样本I指:INTERPRETABLE,可......
  • 004 反射机制——反射机制概念——Java的反射API——反射的步骤——创建对象的2种方式
    2.3.2反射机制的概念(什么是反射)反射机制指在程序运行过程中,对任意一个类都能获取其所有属性和方法,并且任意一个对象都能调用其任意一个方法。这种动态获取类和对象的信......
  • 002 JVM的类加载机制—— JVM的类加载阶段——双亲委派机制
    1.10.1JVM的类加载阶段JVM的类加载分为5个阶段:加载、验证、准备、解析、初始化。在类初始化完成后可以使用该类的信息,在一个类不再被需要时可以从JVM中卸载。1.10.3......
  • 继承中的初始化和加载
    继承关系中的执行顺序代码packageonjava8.extend;/***继承关系中的执行顺序*/classInsect{privateinti=9;protectedintj;{Sy......
  • Summary of Classic Cryptography
    Easybutessential.整理出来方便自己做题的时候查看。单表替换Caesar:原理:凯撒密码(Caesar)加密时会将明文中的每个字母都按照其在字母表中的顺序向后(或向前)移动固定......
  • 肖sir_Java 反射__20
    1.1反射概述Java中创建对象的方式1、使用new关键字:这是我们最常见的也是最简单的创建对象的方式2、使用Clone的方法:无论何时我们调用一个对象的clone方法,JVM就会创建一......
  • javascript:每次只加载3个页面的幻灯(chrome 105.0.5195.125)
    一,js代码:<html><head><metacharset="utf-8"/><title>测试</title><scriptsrc="pcpageapp.js"></script><styletype="text/css">.page......
  • Java_注解与反射
    注解(Java.Annotation)注解入门什么是注解Annotation是从JDK5.0开始引入的新技术Annotation的作用:不是程序本身,可以对程序作出解释(这一点和注释(comment)没什么区别)可以......