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的更多相关文章

  1. 字节码编程,Javassist篇三《使用Javassist在运行时重新加载类「替换原方法输出不一样的结果」》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 通过前面两篇 javassist 的基本内容,大体介绍了:类池(ClassPool) ...

  2. java动态加载类和静态加载类笔记

    JAVA中的静态加载类是编译时刻加载类  动态加载类指的是运行时刻加载类 二者有什么区别呢 举一个例子  现在我创建了一个类  实现的功能假设为通过传入的参数调用具体的类和方法 class offic ...

  3. Java动态加载类在功能模块开发中的作用

    Java中我们一般会使用new关键字实例化对象然后调用该对象所属类提供的方法来实现相应的功能,比如我们现在有个主类叫Web类这个类中能实现各种方法,比如用户注册.发送邮件等功能,代码如下: /* * ...

  4. java reflect 初始学习 动态加载类

    首先要理解Class类: 在java 的反射中,Class.forName("com.lilin.Office") 使用类的全名,这样获取,不仅仅表示了类的类类型,同时还代表着类的 ...

  5. java反射机制与动态加载类

    什么是java反射机制? 1.当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射. IT行业里这么说,没有 ...

  6. Java动态加载类

    详见:https://blog.csdn.net/zai_xia/article/details/80026325 扩展:java反射机制与动态加载类 https://www.cnblogs.com/ ...

  7. Java 反射理解(二)-- 动态加载类

    Java 反射理解(二)-- 动态加载类 概念 在获得类类型中,有一种方法是 Class.forName("类的全称"),有以下要点: 不仅表示了类的类类型,还代表了动态加载类 编 ...

  8. java反射动态加载类Class.forName();

    1,所有的new出来的对象都是静态加载的,在程序编译的时候就会进行加载.而使用反射机制Class.forName是动态加载的,在运行时刻进行加载. 例子:直接上两个例子 public class Ca ...

  9. 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息

    0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...

随机推荐

  1. Xshell连接Ubuntu失败问题

    转自:https://www.linuxidc.com/Linux/2017-08/146222.htm Xshell是一个安全终端模拟软件,可以进行远程登录.我使用XShell的主要目的是在Wind ...

  2. android开发学习---linux下开发环境的搭建&& android基础知识介绍

    一.配置所需开发环境 1.基本环境配置 JDK 5或以上版本(仅有JRE不够) (http://www.oracle.com/technetwork/java/javase/downloads/ind ...

  3. [Spring学习笔记 1 ] Spring 简介,初步知识--Ioc容器详解 基本原理。

    一.Spring Ioc容器详解(1) 20131105 1.一切都是Bean Bean可是一个字符串或者是数字,一般是一些业务组件. 粒度一般比较粗. 2.Bean的名称 xml配置文件中,id属性 ...

  4. Unix awk使用手册

    什么是awk? 你可能对UNIX比较熟悉,但你可能对awk很陌生,这一点也不奇怪,的确,与其优秀的功能相比,awk还远没达到它应有的知名度.awk是什么?与其它大多数UNIX命令不同的是,从名字上看, ...

  5. 如何使用SetTimer

    1.SetTimer定义在那里? SetTimer表示的是定义个定时器.根据定义指定的窗口,在指定的窗口(CWnd)中实现OnTimer事件,这样,就可以相应事件了. SetTimer有两个函数.一个 ...

  6. ML之回归

    一.概述 一元形式: 多元形式: 最小二乘的目标函数

  7. oracle下导出某用户所有表的方法

    oracle下导出某用户所有表的方法 scott/tiger是用户名和密码,handson是导出的实例名 按用户方式导出数据(owner当中写的是用户名) exp scott/tiger@handso ...

  8. mysql_install_db 运行结果

    # /usr/local/mysql/scripts/mysql_install_db \ > --defaults-file=/etc/my.cnf \ > --basedir=/usr ...

  9. Linux内核系统体系概述

    Linux 内核主要由 5 个模块构成,它们分别是: 进程调度模块 用来负责控制进程对 CPU 资源的使用.所采取的调度策略是各进程能够公平合理地访问 CPU,同时保证内核能及时地执行硬件操作. 内存 ...

  10. Java String首字母大写

    一種寫法參考 public String upperFirstChar(String input) { if (input == null || "".equals(input)) ...