首页 > 编程语言 >java SPI机制与双亲委派机制的不同

java SPI机制与双亲委派机制的不同

时间:2022-10-22 15:13:09浏览次数:76  
标签:java springboottest mysqlremark spi SPI UserService 机制 com 加载

 

1、双亲委派机制

1.1 定义

当一个类加载器收到了类加载的请求的时候,他不会直接去加载指定的类,而是把这个请求委托给自己的父加载器去加载。

如果父类为空,交给bootstrap classloader 加载。

如果类还是无法被加载到,则触发findclass,抛出classNotFoundException(findclass这个方法当前只有一个语句,就是抛出classNotFoundException),如果想自己实现类加载器的话,可以继承classLoader后重写findclass方法,加载对应的类)

1.2优点

避免类的重复加载
保护程序安全,防止核心API被随意篡改

2、SPI(service provider interface)定义:

  SPI是jdk内置的一种服务提供发现机制。可以用来启用框架扩展和替换组件,主要是被框架的开发人员使用,比如java.sql.Driver接口,常用的关系型数据有Mysql、Oracle、SQLServer、DB2等,这些不同类型的数据库使用的驱动程序各不相同,那JDK不可能把所有厂商的驱动都实现,只能制定一个标准接口,其他不同厂商可以针对同一接口做出不同的实现,各个数据库厂商根据标准来实现自己的驱动,这就是SPI机制。

 

 

下面看下Mysql的Driver,以com.mysql.cj.jdbc.Driver 为例

 

 

 

 META-INF目录的作用是相当于信息包,用来配置应用程序、扩展程序、类加载器和服务manifest.mf文件,在打包时自动生成。

 

其中manifest.mf里面描述了程序的基本信息、Main-Class的入口、jar依赖路径Class-Path

而META-INFO/services 的作用是实现接口循环实现类的功能, 除了jdbc模块的方案(Driver)之外,还有日志模块的方案(l4j),xml解析模块等。

 

回到正题:

 com.mysql.cj.jdbc.Driver的源码需要往DriverManager进行注册

最终如下图所示,需要往 registeredDrivers 里面进行添加

 

 

而registeredDrivers 变量在 DriverManager 静态初始化的时候会进行调用把真实的类进行加载出来

 

 

例子

创建一个 interface 接口

 

package com.zhianchen.mysqlremark.springboottest.spi;
/*
 *
 *@Description TODO
 *@Author chenzhian
 *@Date 2022/10/21 11:25
 */

public interface UserService {
     void login();
}

 

 

 

 

实现

package com.zhianchen.mysqlremark.springboottest.spi.Impl;

import com.zhianchen.mysqlremark.springboottest.spi.UserService;

/*
 *
 *@Description TODO
 *@Author chenzhian
 *@Date 2022/10/21 11:26
 */

public class AppUserLoginServiceImpl implements UserService {
    @Override
    public void login() {
        System.out.println("AppUserLoginServiceImpl");
    }
}
package com.zhianchen.mysqlremark.springboottest.spi.Impl;

import com.zhianchen.mysqlremark.springboottest.spi.UserService;

/*
 *
 *@Description TODO
 *@Author chenzhian
 *@Date 2022/10/21 11:26
 */

public class PCUserLoginServiceImpl implements UserService {
    @Override
    public void login() {
        System.out.println("PCUserLoginServiceImpl");
    }
}

 

然后在resources 创建目录 META-INF.services  (注意:这里是services 而不是service!!!!!)

创建文件 com.zhianchen.mysqlremark.springboottest.spi.UserService  (这里的文件名要对应UserService包

里面的内容

com.zhianchen.mysqlremark.springboottest.spi.Impl.PCUserLoginServiceImpl
com.zhianchen.mysqlremark.springboottest.spi.Impl.AppUserLoginServiceImpl

 

创建一个Test

/*
 *
 *@Description TODO
 *@Author chenzhian
 *@Date 2022/10/21 14:02
 */
public class SpiTest {
    public static void main(String[] args) {
        ServiceLoader<UserService> serviceLoader= ServiceLoader.load(UserService.class);
        for (UserService userService:serviceLoader
             ) {
            userService.login();
        }
    }
}

 

之前的结果是

PCUserLoginServiceImpl
AppUserLoginServiceImpl

 

参考

纯原创长文-深入理解Java类加载(双亲委派机制及其破坏 JavaSPI和DubboSPI的区别和联系)
面试官:你说你用过Dubbo,那你说说看Dubbo的SPI?

https://www.cnblogs.com/masaike/p/15490402.html

META-INF 作用

Java SPI详解

 

标签:java,springboottest,mysqlremark,spi,SPI,UserService,机制,com,加载
From: https://www.cnblogs.com/zhian/p/16813853.html

相关文章

  • java第三讲-类与对象-ClassAndObjectSourceCode
    1.通过对象变量使用对象  1)直接调用类的方法;(添加和调用get()方法取值)  2)存取类的字段;(设置公有字段)publicclassClassAndObjectTest{publicstaticvoidm......
  • Java的接口和抽象类到底哪个更抽象
    Java的接口和抽象类到底哪个更抽象抽象类抽象方法是是不完整的方法,,它只是进行了声明,没有具体的方法实现逻辑,具体的实现逻辑由子类来完成。包含抽象方法的类是抽象类,通过ab......
  • Java不能继承多个类?内部类帮你解决这个问题
    Java不能继承多个类?内部类帮你解决这个问题内部类在Java中也是一个很重要的概念,很多类中都存在内部类。内部类与内部类的对应的是外围类,内部类可以操作外围类的所有成员,p......
  • 【Java SE】枚举类和注解
    1.枚举类的使用当类的对象由有限个,确定的时候,我们称这种类为枚举类。当需要定义一组常量时,建议使用枚举类。而当枚举类中只有一个对象时,可以使用单例模式。1.1enmu关键......
  • java线程的优先级
    packageA_ShangGuiGu.Thread.ThreadDemo;/***优先级*1.MAX_Priority-----最大优先级为10*2.MIN_Priority-----最小优先级为1*3.NORM_Priority----默认优先级5*4......
  • java基础-->注释
    注释注释:注释起到对代码标注和解释的作用,如果你去看看JDK源码,会发现他们有许多的注释,而且注释是比代码还要多的,可见为代码添加注释是非常重要的,写好注释能让别人更加容易......
  • java第六讲-StreamAndFileSourceCode
    1.PrintStream学习:Java打印流PrintStream类详解_风有点大的博客-CSDN博客_printstream类1.1向文件进行输出PrintStreamps=newPrintStream("helloworld01.txt"......
  • 力扣1235(java)-规划兼职工作(困难)
    题目:你打算利用空闲时间来做兼职工作赚些零花钱。这里有 n 份兼职工作,每份工作预计从 startTime[i] 开始到 endTime[i] 结束,报酬为 profit[i]。给你一份兼职工作......
  • Java--->集合中常用的ArrayList的使用和介绍
    前段时间一直在说数组,今天说下Java集合中常用的ArrayListArrayList类是一个可以动态修改的数组,与普通数组的区别就是ArrayList没有固定大小的限制,可以添加或删除元素。Array......
  • Java并发编程学习9-并发基础Demo
    构建高效且可伸缩的结果缓存本篇我们将逐步构建一个高效且可伸缩的缓存,用于改进一个高计算开销的函数。1.HashMap+并发机制我们首先能想到的就是,通过HashMap和并发......