jvm热部署

1.什么是热部署
2.详细讲解classloader

3.实现一个简单的热部署

1.什么是热部署

什么是热部署:在不重启java虚拟机的前提下,自动检测到class文件的变化,并且更新运行时class行为

2.详细讲解classloader

ClassLoader作用:

1.把class加载到JVM中
2.审查每个类由谁负责加载

3.将class字节码重新解析为JVM统一要求的对象格式

ClassLoader分类:
1.启动类加载器
2.扩展类加载器

3.系统类加载器

4.自定义加载器

类的加载过程:

.class 装载到jvm中, 把原料放到工厂中

虚拟机如何加载这些class文件?

装载.class  验证.class是否符合jvm规范 -->  准备:为类的静态变量分配内存,并将其初始化默认值 --> 解析 -->  初始化:为类的静态变量赋予正确的数值

Classloader的加载机制:

启动类加载器:bootstrap classcloader
作用:装载java核心库

扩展类加载器:Ext classloader
作用:装载jdkhome/lib/ext扩展包 同时可以加自定义:  :-D java.ext.dirs=指定ext目录

应用程序加载器(系统类加载器):app classloader
作用:负责加载java classpath目录下的类或者jar包


自定义加载器(可以有N个): 继承java.lang.ClassLoader

双亲委派模型: 儿子找父亲,父亲找爷爷

应用程序加载器app classloader ->扩展类加载器Ext classloader ->启动类加载器bootstarp classloader 如果启动类加载器找不到: 启动类加载器 ->扩展类加载器 -> 应用程序加载器 一层一层返回来

自定义java.lang.String 能不能打印?

package java.lang;
public class String {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

不能打印,首先加载器会一层一层往上找加载器,当找到启动类加载器时发现java核心类中有该类,所以当运行是运行的是核心类中的String,而核心类中String没有main方法,就报错:

Exception in thread "main" java.lang.NoSuchMethodException: java.lang.String.main([Ljava.lang.String;) 之所以运行不了,它找到顶层中的类加载了

双亲委派模型好处:
1.安全性:保护java核心类不能被覆盖

2.统一性:带着优先级别

对于一个全限定名的java类,只能被加载一次,需要用到自定义类加载器

jvm如何判断两个class是否相同:
1.判断两个类名+全限定名是否形同

2.判断是否有同一个类加载器实施加载的


3.实现一个简单的热部署

/**
 * Created by yz on 2018/2/7.
 * 自定义类加载器
 */
public class MyClassLoader extends ClassLoader {

    /**
     * 重写父类方法 Alt+Insert
     * @param name : 包名+类名路径
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        //将传进来的java文件转换成class文件
        String  fileName = name.substring(name.lastIndexOf(".")+1)+".class";
        InputStream is = this.getClass().getResourceAsStream(fileName);
        try {
            byte[] b = new byte[is.available()];
            is.read(b);
            return defineClass(name,b,0,b.length);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return super.findClass(name);
    }
}

/**

 * Created by yz on 2018/2/7.
 */
public class HelloService {
    public void sayHello(){
        System.out.println("我是hello world version 2");
    }

}

/**
 * Created by yz on 2018/2/7.
 * 热部署原理测试
 */
public class App {
    public static void main(String[] args) throws Exception {
        loadHelo();
        //动态替换class
        System.gc();            //释放当前jvm所占用的class文件,因为装载进去变成正在运行,所以要释放
        Thread.sleep(1000);

        File old = new File("C:\\Users\\yz\\Desktop\\NioDemo\\hostwap-demo\\target\\classes\\com\\yz\\hostwap\\demo\\HelloService.class");
        old.delete();
        File newFile = new File("C:\\Users\\yz\\Desktop\\NioDemo\\hostwap-demo\\HelloService.class");
        newFile.renameTo(old);  //新的文件替换旧的文件
        loadHelo();             //重新装载
    }


    /**
     * 使用自定义类加载器
     * @throws Exception
     */
    public static void loadHelo() throws Exception {
        MyClassLoader loader = new MyClassLoader();
        Class<?> clazz = loader.findClass("com.yz.hostwap.demo.HelloService");
        //通过反射的方式
        Object object = clazz.newInstance();
        Method method = clazz.getMethod("sayHello");
        method.invoke(object);
        System.out.println(object.getClass()+" "+object.getClass().getClassLoader());
    }

}

热部署原理应用:

Tomcat jsp加载:org.apache.jasper.servlet.JasperLoader


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值