V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
EscYezi
V2EX  ›  Java

不懂就问: Spring 是如何扫描到外部依赖中的 Bean 的?

  •  
  •   EscYezi ·
    yeziyezi · 2020-07-02 20:41:30 +08:00 · 4209 次点击
    这是一个创建于 1597 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在练习写一个 Mini Java Web 框架,目前实现了简单的 ioc,模仿 Spring 指定一个启动类,然后扫描这个类所在包及其子包,找到所有标记 @Component 的类并处理依赖,过程还算顺利。然后问题来了,如何扫描到由外部引入的依赖中的 Bean ?如果扫描不到的话,外部依赖中的 bean 无法用框架来自动管理,扩展性就下降了很多。

    查找一番,只找到了这么一段话

    利用 starter 实现自动化配置只需要两个条件——maven 依赖、配置文件。引入 maven 实质上就是导入 jar 包,spring-boot 启动的时候会找到 starter jar 包中的 resources/META-INF/spring.factories 文件,根据 spring.factories 文件中的配置,找到需要自动配置的类。

    如果在外部依赖的配置文件中写好了哪些包需要被扫描,然后 spring-boot 读这个配置文件就行了。但 Spring 是怎么知道有哪些依赖并且去这些依赖的 classpath 下查找的?感觉像是在 maven 插件里对依赖进行了扫描,但又不知道自己的判断是否正确。或者有没有可以在运行时就可以扫描到全部依赖的办法(仅通过 maven 引入,在工程中没有 import 依赖也可以扫描到的那种)

    PS:目前使用的是 classgraph 来扫描指定包下的类

    第 1 条附言  ·  2020-07-06 22:34:04 +08:00
    感谢各位 V 友指点,先用 SPI 来实现这个功能了,之后有需要的话会尝试全量扫描的方式来实现
    10 条回复    2020-07-06 22:32:12 +08:00
    chihiro2014
        1
    chihiro2014  
       2020-07-02 21:33:22 +08:00   ❤️ 1
    https://space.bilibili.com/2494318/video
    之前我记得这个 up 讲过 Spring 生命周期这块,不太清楚视频是不是还在,好像下架了
    讲那块的时候,很详细的提过如何写这块内容
    cheng6563
        2
    cheng6563  
       2020-07-02 21:54:14 +08:00 via Android   ❤️ 1
    实际上 spring 是直接打开 jar 包扫描里面的文件。这也是 spring 启动慢的原因之一吧
    xiangwan
        3
    xiangwan  
       2020-07-02 22:04:08 +08:00   ❤️ 1
    貌似是 jvm 的 ClascLoader 帮忙加载的
    lqw3030
        4
    lqw3030  
       2020-07-02 22:21:15 +08:00   ❤️ 1
    由 tomcat 的类加载器加载的
    ingin
        5
    ingin  
       2020-07-02 22:37:55 +08:00   ❤️ 1
    可以看下 conditionalon 相关注解的使用
    ninblue
        6
    ninblue  
       2020-07-03 01:16:23 +08:00 via iPhone   ❤️ 1
    一般都是扫 AutoConfiguration 类上的 ConditionOnClass 注解,有实现类就加载,没有就跳过
    zhaorunze
        7
    zhaorunze  
       2020-07-03 09:30:37 +08:00   ❤️ 1
    是全量扫描,多跟几遍源码就懂了,源码不会骗人
    ansyx
        8
    ansyx  
       2020-07-03 10:06:48 +08:00   ❤️ 1
    SPI
    huifukejian
        9
    huifukejian  
       2020-07-04 21:05:29 +08:00   ❤️ 1
    所有的类和配置文件都会读取, 包括第三方依赖。如果分模块开发原理其实也是一样,service.jar 引入 dao.jar, 在 service 启动的时候,spring 就会读取 dao.jar, 生成 bean 然后注入到 service
    EscYezi
        10
    EscYezi  
    OP
       2020-07-06 22:32:12 +08:00
    @ansyx 研究了一下 SPI,可以实现预想中的效果,非常感谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2877 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 03:44 · PVG 11:44 · LAX 19:44 · JFK 22:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.