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 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...
随机推荐
- 【DeepLearning】用于几何匹配的卷积神经网络体系结构
[论文标题]Convolutional neural network architecture for geometric matching (2017CVPR) [论文作者]Ignacio Rocc ...
- java hibernate Criteria 删除数据 delete data 2种方法
public String deleteByUserAccount(String account) { 方式一: Session session = this.getCurrentSession(); ...
- 浅谈 iOS 与 H5 的交互- JavaScriptCore 框架
前言 小的作为一个iOS程序猿,可能研究JavaScript以及H5相关的知识并不是为了真正的要去转行做这一方面,其实更多的为了要研究OC中的JavaScriptCore框架,JavaScriptCo ...
- 构建高性能数据库缓存之redis主从复制
一.什么是redis主从复制? 主从复制,当用户往Master端写入数据时,通过Redis Sync机制将数据文件发送至Slave,Slave也会执行相同的操作确保数据一致:且实现Redis的主从复制 ...
- Redis学习之路(002)- Ubuntu下redis开放端口
Redis在ubuntu安装后默认是只有本地访问,需要别的ip访问我们需要修改redis的配置文件 1. dpkg -L redis-server 这命令我们可以看到redis的安装的文件在那些目录 ...
- 【NotePade++】NotePade++如何直接编译运行java文件
安装Notepad++和JDK(略): Notepad++的菜单栏:插件->Plugin Manager->Show Plugin Manager,Available中勾选NppExec, ...
- Swift 值类型/引用类型
1.值类型/引用类型 在 Swift 语言中,所有的类型都可以被分为 "值类型" 或者 "引用类型",可以将其理解为函数参数传递的方式. 值类型表示的是将它传递 ...
- Bitnami Redmine 中文附件名 报错修复
最近自己在服务器上搭了个redmine,用的是Bitnami的一键安装程序. 搭好后,运行得不错,居然还增加了负载均衡. 某天上传中文附件,打开报内部错误,去redmine官网看了下,果然有这个问题, ...
- win7下 go语言开发环境搭建(64bit)
Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全.支持并行进程 ...
- nginx Server names
通配符名称 正則表達式名称 混合名称 优化 兼容性 server名称定义使用的server_name指令和决定哪个server块用于一个给定的请求. 參见"怎样Nginx处理一个请求&quo ...