Java运行时动态加载类之ClassLoader
https://blog.csdn.net/fjssharpsword/article/details/64922083
***************************************************************************
需求场景:动态加载类ClassLoaderd,在xml文件中配置加载类名称和方法,:
一、准备
1)在D:\\tmp\\目录下配置a.xml文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<classes> <class name="User">
<method>say</method>
</class> <class name="map">
<method>add</method>
</class> </classes>
2)要动态加载的类:
package dx;
public class map {
public void add(){
System.out.println("1+1=2");
}
}
package cn.fjs;
public class User {
public void say(){
System.out.println(" hello ...");
}
}
对这两个类进行编译后,将class文件复制到D:\\tmp\\路径下。
二、参考代码如下
1、重载ClassLoader类:
package cn.fjs; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream; public class DynamicClassLoader extends ClassLoader{ private static final String SUFFIX = ".class";
public String[] paths; public DynamicClassLoader(String[] paths) {
this.paths = paths;
} public DynamicClassLoader(ClassLoader parent,String[] paths){
super(parent);
this.paths = paths;
} @SuppressWarnings("deprecation")
@Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
String classPath = getClassPath(className);
if(classPath != null){
byte[] clazz = loadClazz(classPath);
return defineClass(clazz, 0, clazz.length);
}else{
System.out.println("class is not found !");
return null;
}
} public byte[] loadClazz(String classPath) {
try {
FileInputStream in = new FileInputStream(new File(classPath));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int b;
while((b = in.read()) != -1){
baos.write(b);
}
in.close();
return baos.toByteArray();
} catch (Exception e) {
System.out.println(e);
}
return null;
} public String getClassPath(String className){
for(String path : paths){
if(className.contains(".")){
className = className.replaceAll(".", File.separator);
}
String classPath = path + className + SUFFIX;
File classFile = new File(classPath);
if(classFile.exists()){
return classPath;
}
}
return null;
}
}
2、解析xml文件
package cn.fjs; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; //解析xml文件,获取类和方法
public class DynamicDom {
private static DocumentBuilderFactory dbFactory = null;
private static DocumentBuilder db = null;
private static Document document = null; static{
try {
dbFactory = DocumentBuilderFactory.newInstance();
db = dbFactory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
} public Map<String,List<String>> getMethods(String fileName) throws SAXException, IOException{
Map<String,List<String>> classes = new HashMap<String, List<String>>();
document = db.parse(fileName);
NodeList nList = document.getElementsByTagName("class");
for(int i = 0 ; i<nList.getLength();i++){
Node node = nList.item(i);
Element ele = (Element)node;
if(node.getNodeType() == Element.ELEMENT_NODE){
String clazz = ele.getAttribute("name");
List<String> methods = new ArrayList<String>();
String method = ele.getElementsByTagName("method").item(0).getTextContent();
methods.add(method);
classes.put(clazz, methods);
}
}
return classes;
}
}
3、测试类:
package cn.fjs; import java.util.List;
import java.util.Map;
import cn.fjs.DynamicClassLoader;
import cn.fjs.DynamicDom; public class DynamicClassLoaderTest {
public static void main(String[] args) {
DynamicDom dmo = new DynamicDom();//xml文件解析类
Map<String, List<String>> classes;
//重载ClassLoader类
DynamicClassLoader loader = new DynamicClassLoader(new String[]{"D:\\tmp\\"});
try {
classes = dmo.getMethods("D:\\tmp\\a.xml");
for(String key:classes.keySet()){
for(String clazz : classes.get(key)){
Class<?> c =loader.findClass(key);//类名字
c.getMethod(clazz).invoke(c.newInstance());//方法名字
}
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
执行结果:
hello ...
1+1=2
Java运行时动态加载类之ClassLoader的更多相关文章
- 字节码编程,Javassist篇三《使用Javassist在运行时重新加载类「替换原方法输出不一样的结果」》
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 通过前面两篇 javassist 的基本内容,大体介绍了:类池(ClassPool) ...
- java动态加载类和静态加载类笔记
JAVA中的静态加载类是编译时刻加载类 动态加载类指的是运行时刻加载类 二者有什么区别呢 举一个例子 现在我创建了一个类 实现的功能假设为通过传入的参数调用具体的类和方法 class offic ...
- Java动态加载类在功能模块开发中的作用
Java中我们一般会使用new关键字实例化对象然后调用该对象所属类提供的方法来实现相应的功能,比如我们现在有个主类叫Web类这个类中能实现各种方法,比如用户注册.发送邮件等功能,代码如下: /* * ...
- java reflect 初始学习 动态加载类
首先要理解Class类: 在java 的反射中,Class.forName("com.lilin.Office") 使用类的全名,这样获取,不仅仅表示了类的类类型,同时还代表着类的 ...
- java反射机制与动态加载类
什么是java反射机制? 1.当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射. IT行业里这么说,没有 ...
- Java动态加载类
详见:https://blog.csdn.net/zai_xia/article/details/80026325 扩展:java反射机制与动态加载类 https://www.cnblogs.com/ ...
- Java 反射理解(二)-- 动态加载类
Java 反射理解(二)-- 动态加载类 概念 在获得类类型中,有一种方法是 Class.forName("类的全称"),有以下要点: 不仅表示了类的类类型,还代表了动态加载类 编 ...
- java反射动态加载类Class.forName();
1,所有的new出来的对象都是静态加载的,在程序编译的时候就会进行加载.而使用反射机制Class.forName是动态加载的,在运行时刻进行加载. 例子:直接上两个例子 public class Ca ...
- 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息
0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...
随机推荐
- 使用Thrift让Python为Java提供服务
Thrift是基于TCP的,谷歌的GRPC是基于HTTP的.Thrift和GRPC都是比直接写个web接口进行调用更完美的方式,最明显的一点就是:我们可以定义结构体,避免了手动解析的过程. 但是,在将 ...
- C语言open()函数:打开文件函数(转)
相关函数:read, write, fcntl, close, link, stat, umask, unlink, fopen 头文件:#include <sys/types.h> ...
- rviz学习笔记(一)——Markers: Sending Basic Shapes (C++) 发送基础形状
一.创建一个包——进行marker练习 1.创建ROS工作空间和包 mkdir -p ~/catkin_ws/src #创建工作空间目录 #创建ROS数据包 catkin_create_pkg usi ...
- ajax提交出现的问题记载
1.普通ajax提交的时候是没法提交input type=file的,换句话说$_FILES获取不到ajax提交过去的值. 2.ajax提交的时候,设置dataType="json" ...
- webpack window dev-server配置
1.安装webpack dev-server npm install --save-dev webpack webpack-dev-server 著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...
- 【java】自定义异常类
目录结构: contents structure [+] 为什么需要自定义异常类 自定义异常的方式 实例 日常日志 一,为什么需要自定义异常类 当java中的异常类型没有能够满足我们所需的异常的时候就 ...
- 【转】Swift 语言的设计错误
Swift 语言的设计错误 在『编程的智慧』一文中,我分析和肯定了 Swift 语言的 optional type 设计,但这并不等于 Swift 语言的整体设计是完美没有问题的.其实 Swift 1 ...
- JavaScript 如何从引用类型(Array 、 Object)创建一个新的对象
数组的增删改 1.新增一项可以使用concat方法,它不会对原有数组进行改动,而是创建一个新数组 let a = [0, 1, 2] let b = a.concat([3]) console.log ...
- 常用代码之五:RequireJS, 一个Define需要且只能有一个返回值/对象,一个JS文件里只能放一个Define.
RequireJS 介绍说一个JS文件里只能放一个Define,这个众所周知,不提. 关于Define,它需要有一个返回值/对象,且只能有一个返回值/对象,这一点却是好多帖子没有提到的,但又非常重要的 ...
- Xilinx 常用模块汇总(verilog)【01】
作者:桂. 时间:2018-05-07 19:11:23 链接:http://www.cnblogs.com/xingshansi/p/9004492.html 前言 该文私用,不定期更新,主要汇总 ...