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. HDUOJ-----Climbing Worm

    Climbing Worm Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...

  2. 关于去哪儿网的UI自动化测试脚本

    UI自动化测试Qunar机票搜索场景访问Qunar机票首页http://flight.qunar.com,选择“单程”,输入出发.到达城市,选择today+7日后的日期,点“搜索”,跳转到机票单程搜索 ...

  3. 【Spring】SpringMVC中浅析数据的传递方式

    包括了基本数据类型的传递和 Date数据类型的传递.关于SpringMVC的配置可以参见基于注解实现SpringMVC+MySQL 假设有表单页面如下: <h1>登录</h1> ...

  4. Git 别名(分布式版本控制系统)

    1.Git 别名 Git 并不会在你输入部分命令时自动推断出你想要的命令.如果不想每次都输入完整的 Git 命令,可以通过 git config 文件来轻松地为每一个命令设置一个别名.这里有一些例子你 ...

  5. IDEA使用笔记(一)——使用前的基本设置

    前言:记忆不好,有些东西需要的时候又需要找一找,那就不如让“纸和笔”来帮忙记录一下啦!到时候查找也方便,而且是自己的东西印象更加的深刻,说不定还能帮助到他人多好玩的事情! 软件的下载.安装就不记啦!自 ...

  6. 获取资源文件 r.drawable中的图片转换为drawable、bitmap

    1. Resources resources = mContext.getResources(); Drawable drawable = resources.getDrawable(R.drawab ...

  7. linux的0号进程和1号进程

    linux的 0号进程 和 1 号进程 Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2) * idle进程由系统自动创 ...

  8. Fuel4d 2.3 公布

    [版本号编号]:Fuel4D 2.3. [公布日期]:2014年10月20日. [编译环境]:UNICODE.VS2010.x86. [开发环境]:ANSI/UTF-8/UNICODE.VS2005/ ...

  9. Effective C++ 34

    34.将文件间的编译依赖性降到最低. 对于一个大型程序,其结构是错综复杂的.当你对一个类进行一些改动时.改动的不是接口,而是类的实现,即仅仅是一些细节部分,但又一次生成程序时,所实用到这个类的的文件都 ...

  10. Hive 打开调试模式

    编程过程中发现错误,无法看到具体的错误信息,网上搜了下,按照下面的方法启动Hive Shell就可以打开调试(注意:此方法只对本次回话有效): hive --hiveconf hive.root.lo ...