Nvwa——JFramework之热加载、IOC

u010234286 2018-03-16 07:08:44
github地址:https://github.com/gugumall/JFramework
完整项目介绍:https://bbs.csdn.net/topics/392340442
开发文档:https://www.gugumall.cn/downloads/JFrameworkDoc.docx

本来想把代码都贴出来的,结果超出帖子长度了,有兴趣的朋友去github下载吧

实现热加载的类加载器:
package j.nvwa;

public abstract class NvwaClassLoader extends java.lang.ClassLoader {
/**
*
*
*/
public NvwaClassLoader() {
super();
}

/**
*
* @param path
* @param jarpath
* @return
* @throws Exception
*/
public abstract NvwaClassLoader getInstance(String path,String jarpath)throws Exception;

/**
*
* @param classpath
* @param jarpath
*/
public abstract void setClasspath(String classpath,String jarpath);

/**
*
* @param name
* @return
* @throws Exception
*/
protected abstract boolean needRenew(String name)throws Exception;
}


package j.nvwa;

import j.util.ConcurrentMap;
import j.util.JUtilInputStream;
import j.util.JUtilString;
import j.util.JUtilTimestamp;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
* 自动检查类文件是否更新,如更新则自动重新加载
*
* @author JFramework
*
*/
public class NvwaClassLoaderAutoRenew extends NvwaClassLoader {
private String classpath;// 类文件存放根目录
private String jarpath;// jar文件存放根目录

private static ConcurrentMap classes = new ConcurrentMap();// 已加载的类
private static ConcurrentMap lastModified = new ConcurrentMap();// 类文件上次修改时时间
private static ConcurrentMap jarFileLocations=new ConcurrentMap();
private static ConcurrentMap instances = new ConcurrentMap();// 键:类文件存放根目录 值:与之对应的ClassLoaderAutoUpdate实例

/**
*
*
*/
public NvwaClassLoaderAutoRenew() {
super();
}

/*
* (non-Javadoc)
* @see j.nvwa.NvwaClassLoader#setClasspath(java.lang.String, java.lang.String)
*/
public void setClasspath(String classpath,String jarpath){
this.classpath=classpath;
this.jarpath=jarpath;
}

/*
* (non-Javadoc)
* @see j.nvwa.NvwaClassLoader#getInstance(java.lang.String, java.lang.String)
*/
public NvwaClassLoader getInstance(String path,String jarpath)throws Exception {
if (!instances.containsKey(path+jarpath)) {
NvwaClassLoaderAutoRenew loader = new NvwaClassLoaderAutoRenew();
Field field = ClassLoader.class.getDeclaredField("parent");
field.setAccessible(true);
field.set(loader,Nvwa.defaultClassLoader);


loader.setClasspath(path,jarpath);
instances.put(path+jarpath, loader);
}
return (NvwaClassLoader) instances.get(path+jarpath);
}

/*
* (non-Javadoc)
* @see j.nvwa.NvwaClassLoader#renew(java.lang.String)
*/
protected boolean needRenew(String name)throws Exception{
if (!responsible(name)){
return false;
}

try {
name = name.intern();
synchronized (name) {
String filePath = getFile(this.classpath,name);

File file = new File(filePath);
if (!file.exists()){
return false;
}

long latestUpd = file.lastModified();
file = null;

if (classes.containsKey(name) && lastModified.containsKey(name)) {// 已经加载过,判断是否已更新
Long lastUpd = (Long) lastModified.get(name);

return (lastUpd.longValue() != latestUpd);
}
}
}catch (Exception e) {
e.printStackTrace();
}
return false;
}

/**
*
* @param path
* @param jarpath
* @return
* @throws Exception
*/
private NvwaClassLoader getNewInstance(String path,String jarpath)throws Exception {
NvwaClassLoaderAutoRenew loader = new NvwaClassLoaderAutoRenew();
loader.setClasspath(path,jarpath);
return loader;
}

/*
* (non-Javadoc)
* @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
*/
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (!responsible(name)){
return Nvwa.defaultClassLoader.loadClass(name);
}

try {
name = name.intern();
synchronized (name) {
String filePath = getFile(this.classpath,name);

boolean inJar=false;

File file = new File(filePath);
if (!file.exists()){
String inJarFilePath=getJarFile(name);
if(inJarFilePath==null){
throw new ClassNotFoundException("class file is not exists - "+name);
}else{
file=new File(inJarFilePath);
inJar=true;
}
}

long latestUpd = file.lastModified();
file = null;

if (classes.containsKey(name) && lastModified.containsKey(name)) {// 已经加载过,判断是否已更新
Long lastUpd = (Long) lastModified.get(name);

if (lastUpd.longValue() == latestUpd) {// 未更新且已经加载
return (Class) classes.get(name);
}else{//更新了,重新加载
System.out.println(JUtilTimestamp.timestamp()+" j.nvwa.NvwaClassLoaderAutoRenew renew "+name);
NvwaClassLoaderAutoRenew newLoader=(NvwaClassLoaderAutoRenew)getNewInstance(this.classpath,this.jarpath);
Class clazz=defineClazz(newLoader,resolve,latestUpd,name,inJar);
return clazz;
}
}else{
Class clazz=defineClazz(this,resolve,latestUpd,name,inJar);
return clazz;
}
}
}catch (Exception e) {
e.printStackTrace();
}

throw new ClassNotFoundException();
}

/**
*
* @param loader
* @param resolve
* @param latestUpd
* @param name
* @param inJar
* @return
* @throws Exception
*/
private Class defineClazz(NvwaClassLoaderAutoRenew loader,boolean resolve,long latestUpd,String name,boolean inJar) throws Exception{
byte[] classData = loader.loadClassData(name,inJar);

Class clazz = loader.defineClass(name, classData, 0,classData.length);
if(resolve) loader.resolveClass(clazz);

lastModified.put(name,new Long(latestUpd));
classes.put(name,clazz);

return clazz;
}

/**
* 判断是否由ClassLoaderAutoUpdate进行加载
* @param name
* @return
*/
private boolean responsible(String name){
return Nvwa.isDefinedImplementation(name);
}

/**
* get class file path from full name of class
*
* @param root - root path of classes
* @param classname - full name of class
* @return
*/
private String getFile(String root, String classname) {
return root + JUtilString.replaceAll(classname, ".", File.separator)+ ".class";
}

/**
*
* @param name
* @param inJar
* @return
* @throws IOException
*/
private byte[] loadClassData(String name,boolean inJar) throws Exception {
if(!inJar){
String filePath = getFile(this.classpath, name);

File file = new File(filePath);
if (file.exists() && file.isFile()) {
return JUtilInputStream.bytes(new FileInputStream(filePath));
} else {
throw new IOException("file of class " + name + " not found.");
}
}else{
String entryName=JUtilString.replaceAll(name, ".", "/")+".class";
String jarFilePath=getJarFile(name);
JarFile jar=new JarFile(getJarFile(name));
JarEntry en=jar.getJarEntry(entryName);

byte[] bs=JUtilInputStream.bytes(jar.getInputStream(en));
System.out.println("data of jar file "+name+" in "+jarFilePath+" loaded,the size is - "+bs.length);

jar.close();
return bs;
}
}

/**
* get class file path from full name of class
*
* @param root - root path of classes
* @param classname - full name of class
* @return
*/
private String getJarFile(String classname) throws Exception{
if(jarpath==null) return null;

if(jarFileLocations.containsKey(classname)) return (String)jarFileLocations.get(classname);

File jarDir=new File(jarpath);
if(!jarDir.isDirectory()||!jarDir.exists()) return null;

File[] jars=jarDir.listFiles();
for(int i=0;i<jars.length;i++){
if(!jars[i].getName().toLowerCase().endsWith(".jar")) continue;

String entryName=JUtilString.replaceAll(classname, ".", "/")+".class";

JarFile jar=new JarFile(jars[i]);
JarEntry en=jar.getJarEntry(entryName);
if(en!=null&&!en.isDirectory()){
System.out.println("find "+classname+" in jar "+jars[i].getAbsolutePath()+","+en.getCompressedSize());
jarFileLocations.put(classname,jars[i].getAbsolutePath());

jar.close();
return jars[i].getAbsolutePath();
}

jar.close();
}

return null;
}
}

...全文
463 回复 打赏 收藏 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
打开链接下载源码: https://pan.quark.cn/s/d85aa9a28238 FreeRTOS,其全称为“Free Real-Time Operating System”,是一款具备开源特质且设计轻巧的实时操作系统(RTOS),主要应用于嵌入式系统领域。该“freertos工程文件以及官方文档.rar”压缩包内含了与FreeRTOS关联的工程文件、官方文档资料以及其他用于移植的文件,是进行FreeRTOS学习与应用的关键性资源。 FreeRTOS的核心特质涵盖任务调度机制、中断处理功能、同步机制设计以及内存管理策略。其中,任务调度机制是其核心功能,借助优先级抢占式调度算法,保障高优先级任务能够获得及时响应。中断处理功能是嵌入式系统中的关键环节,FreeRTOS支持在中断执行环境中开展特定操作,同时确保任务执行状态的安全。同步机制例如信号量、互斥量及事件标志组,主要用于实现任务之间的通信与协调。内存管理部分则负责动态分配和释放内存资源,以满足不同任务的特定需求。 工程文件通常由源代码、配置文件、编译脚本等构成,能够帮助开发者深入理解FreeRTOS的工作原理,并在此基础上进行定制化开发。例如,`FreeRTOSConfig.h`作为FreeRTOS的核心配置文件,允许用户依据目标硬件条件和应用需求调整内核参数,比如任务数量、堆大小等。 官方文档资料是学习FreeRTOS的重要参考资料,其内容详尽地阐述了系统架构、API函数、应用示例等关键信息。通过研读这些文档,开发者可以掌握如何创建任务、配置中断、实现任务间的同步与通信,以及如何对FreeRTOS系统进行调试和优化。 移植文件主要涉及将FreeRTOS部署于不同的微控制器(MCU)或硬件平台之上。每个平...

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧