Mybatis基础-资源加载

一、类加载器

类加载机制:双亲委派机制,自下向上检查类是否已加载,自上向下加载类。

类的加载时机:在使用的时候就会加载。

常用的类加载器:

BootStrapClassLoader:启动类加载器,加载路径为/jre/lib包下如:rt.jar

ExtClassLoader:扩展类加载器,加载路径/jre/lib/ext包下jar

AppClassLoader:应用程序类加载器,加载路径为classpath,如我们自定义的类和引入的第三方jar。

加载顺序:BootStrapClassLoader> ExtClassLoader> AppClassLoader

    public static void main(String[] args) {
        //这三行代码在Launcher类中均有体现。
        //获取bootstrap classloader的加载路径
        System.out.println(System.getProperty("sun.boot.class.path"));
        //获取ext classloader的加载路径
        System.out.println(System.getProperty("java.ext.dirs"));
        //获取app classloader的加载路径
        System.out.println(System.getProperty("java.class.path"));
    }

类加载器语义上的父子关系

ClassLoader中的parent属性:用于指定类加载器的父类加载器是谁,如图,在创建AppClassLoader时指定了ExtClassLoader为它的parent(父类加载器),创建ExClassLoader时没有指定父类加载器(null),则表示他的父类加载器是BootstrapClassLoader。这里说的父类并非继承关系,AppClassLoader和ExtClassLoader均继承了URLClassLoader。

双亲委派机制

findClass:当前类加载器 实际执行加载二进制流的具体行为方法。

可以从下而上加载类文件吗?不可以,一般来说rt.jar中某些文件会在初始化时就开始加载,如果从下而上加载,那么无法校验这些class是否已加载过,倒是jvm中可能存在同一包下一个类有两个类文件,导致jvm的不安全不稳定。

自定义类加载器

//自定义类加载器,加载非classpath下的类文件
class MyClassLoader extends ClassLoader {
    private String FILE_LOCATION = "D://";

    public MyClassLoader() {
        //父加载器默认为AppClassLoader
    }

    @Override
    protected Class<?> findClass(String name) {
        try {
            //name com.payment.service.impl.JDKProxy
            InputStream inputStream = new FileInputStream(FILE_LOCATION
                    .concat(name.replaceAll("\\.", "/"))
                    .concat(".class"));
            ByteArrayOutputStream byteArrayInputStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int count;
            while ((count = inputStream.read(bytes)) != -1) {
                byteArrayInputStream.write(bytes, 0, count);
            }
            byte[] data = byteArrayInputStream.toByteArray();
            return defineClass(name, data, 0, data.length);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        try {
            MyClassLoader classLoader = new MyClassLoader();
            Class<?> aClass = classLoader.findClass("com.payment.service.impl.JDKProxy");
            Object jdkProxy = aClass.newInstance();
            Method method = aClass.getMethod("print");
            method.invoke(jdkProxy);

            //JDKProxy jdkProxy =(JDKProxy)aClass.newInstance();
            //该操作JDKProxy会被加载两次,一次是MyClassLoader,一次是AppClassLoader,
            //类型转换时会抛异常ClassCastException
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

二、单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

懒汉式:类加载时便创建对象,如果创建对象会消耗大量资源,则应该延时加载该对象。

class Singleton {
    //Singleton类加载时便创建Singleton对象,因为类只会加载一次,因此Singleton对象只会创建一次
    private static final Singleton instance = new Singleton();

    //构造方法私有,防止new对象
    private Singleton() {
    }

    //提供全局唯一的访问点
    public static Singleton getInstance() {
        return instance;
    }
}

懒汉式:延时加载对象,当真正使用对象时再创建。

class Singleton {
    //volatile 防止指令重排,先完成初始化再赋值。
    private static volatile Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        //第一次检测
        if (instance == null) {
            //加锁
            synchronized (Singleton.class) {
                //第二次检测
                if (instance == null) {
                    //指令重排出现位置,如果赋值操作在Singleton实例化完成前,那么另一个线程
                    //得到的可能是一个未初始化完成的对象。
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

内部类:类加载过程由类加载器加锁,从而保证线程安全。

class Singleton {
    private Singleton() {
    }

    //虽然是static修饰,Singleton类加载的时候不会加载SingletonHolder类,
    //只有使用到SingletonHolder类时才会加载。
    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        //触发SingletonHolder类加载
        return SingletonHolder.instance;
    }
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值