我在运行时创建一个类文件。
我想用类加载器中的更新的类文件替换现有的类文件。
它类似于避免服务器重新启动和重新部署的热交换(例如 JRebel)。
我找到了用于上下文重新加载的 tomcat 的 context.xml 方法。但在生产环境中它不是很有用。
我们可以在运行时向 ClassLoader 注册类吗?请建议是否有任何替代方法可以在运行时重新加载类。
我正在使用以下代码来检索当前的类加载器。
ClassLoader classLoader = LoggingAspect.class.getClassLoader();
下面是加载类方法的实现。
public class AspectClassLoader extends ClassLoader{
@Override
public synchronized Class<?> loadClass(String name) throws ClassNotFoundException
{
String customLoadClass = "com.log.LoggingAspect";
try
{
if(!customLoadClass.equals(name))
{
return super.loadClass(name);
}
else
{
URL classLoadUrl = new URL(this.reloadClassUrl);
URLConnection connection = classLoadUrl.openConnection();
InputStream input = connection.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int data = input.read();
while(data != -1){
buffer.write(data);
data = input.read();
}
input.close();
byte[] classData = buffer.toByteArray();
return defineClass(name, classData, 0, classData.length);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
要重新加载课程,我正在使用以下代码。
AspectClassLoader urlClsLoader = new AspectClassLoader(classLoader);
Class aspect = urlClsLoader.reloadClass("com.log.LoggingAspect", true, new String("file:"+className));
我的类加载器的重载方法是
public synchronized Class<?> reloadClass(String name, boolean resolve, String reloadClassUrl) throws ClassNotFoundException
{
this.reloadClassUrl = reloadClassUrl;
return this.loadClass(name, resolve);
}
重新加载后,如果我创建 LoggingAspect 的新实例,它仍然会给我旧实例。请建议。
Class aspect = urlClsLoader.reloadClass("com.log.LoggingAspect", true, new String("file:"+className));
com.log.aspect.Aspect aspectObj = (com.log.aspect.Aspect)aspect.newInstance();
我仍然得到旧实例。
请建议为什么类加载器不加载修改后的类?