一灰灰blog 一灰灰blog
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)

一灰灰blog

资深搬运工
首页
  • InfluxDB
  • MongoDB
  • MySql
  • 基础系列
  • DB系列
  • 搜索系列
  • MQ系列
  • WEB系列
  • 中间件
  • 运维
  • SpringSecurity
  • SpringCloud
  • QuickAlarm
  • QuickCrawer
  • QuickFix
  • QuickMedia
  • QuickSpi
  • QuickTask
  • 高可用
  • 分类
  • 标签
  • 归档
  • 收藏
  • 关于
GitHub (opens new window)
  • 基础系列

    • 配置

    • AOP

    • Bean

      • 【基础系列】Bean之基本定义与使用
      • 【基础系列】Bean之自动加载
        • I. AutoConfiguration
          • 1. 包路径扫描使用姿势
          • 2. 定义Bean使用方式
          • 3. 实例演示
          • 4. 小结
        • II. 其他
          • 0. 相关
          • 1. 一灰灰Blog
          • 2. 声明
          • 3. 扫描关注
      • 【基础系列】Bean之动态注册
      • 【基础系列】Bean之注销与动态注册实现服务mock(应用篇)
      • 【基础系列】Bean之条件注入@Condition使用姿势
      • 【基础系列】Bean之@ConditionalOnBean与@ConditionalOnClass
      • 【基础系列】Bean之条件注入@ConditionalOnExpression
      • 【基础系列】Bean之条件注入@ConditionalOnProperty
      • 【基础系列】Bean之多实例选择
      • 【基础系列】FactoryBean及代理实现SPI机制的实例(应用篇)
      • 【配置系列】Bean加载顺序之错误使用姿势辟谣
      • 【基础系列】指定Bean初始化顺序的若干姿势
      • 【基础系列】从0到1实现一个自定义Bean注册器(应用篇)
      • 【基础系列】自动配置选择生效
      • 【基础系列-实战】如何指定bean最先加载(应用篇)
      • 【基础系列】实现一个自定义的@Autowired(应用篇)
      • 【基础系列】SpringContext.getBean()方法调用导致NPE?
    • SpEL

    • 事件

    • 国际化

    • 定时器

    • 日志

  • DB系列

  • 搜索系列

  • MQ系列

  • WEB系列

  • 中间件

  • 运维

  • SpringSecurity

  • SpringCloud

  • Spring系列
  • 基础系列
  • Bean
一灰灰
2018-10-12

【基础系列】Bean之自动加载

前面一篇介绍了Bean的常用姿势,在一个项目中,可能不会出现什么问题,可如果你提供了一个Jar包供第三方用户使用,那么你这个jar包中的Bean,能被第三方加载么?

本篇博文将主要介绍AutoConfig相关的内容,即如果我想提供一个jar包供第三方在Spring的环境下使用时,可以怎么做

# I. AutoConfiguration

通常来讲,要想实现上面的场景,建议是借助@Configuration注解的配置类来管理你自己的bean,这样对于其他使用方而言,只需要加载到你的配置类,就可以注册你的所有bean了

# 1. 包路径扫描使用姿势

首先是在你的工程中定义一个配置类,如下

@Configuration
@ComponentScan("com.git.hui.boot.autoconfig")
public class SelfAutoConfig {
}
1
2
3
4

这个配置类功能比较简单,指明扫描的包路径,然后这个配置类如何给使用方使用呢?

将配置放在指定的文件中即可,使用者会自动加载,从而避免的代码的侵入

  • 在资源目录下新建目录 META-INF
  • 在 META-INF 目录下新建文件 spring.factories
  • 在文件中添加 org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.git.hui.boot.autoconfig.SelfAutoConfig

说明,如果需要换行时,可以如下

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.git.hui.boot.autoconfig.SelfAutoConfig,`
    com.git.hui.boot.autoconfig.SelfAutoConfig2,`
1
2
3

然后使用方就可以愉快的使用你的bean了,定义一个测试的Bean如下

@Slf4j
@Component
public class AutoBean {
    private String name;

    public AutoBean() {
        this("defaultAutoBean");
    }

    public AutoBean(String name) {
        this.name = name;
        log.info("AutoBean load time: {}", System.currentTimeMillis());
    }

    public String getName() {
        return name;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 2. 定义Bean使用方式

直接在Config配置中,定义Bean,可以说是更加常见的方式,特别是当你的bean不是那么多的时候,推荐使用这种方式,便于集中管理

@Slf4j
public class AutoConfBean {
    private String name;

    public AutoConfBean(String name) {
        this.name = name;
        log.info("AutoConfBean load time: {}", System.currentTimeMillis());
    }

    public String getName() {
        return name;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

对应的配置类

@Configuration
@ComponentScan("com.git.hui.boot.autoconfig")
public class SelfAutoConfig {

    @Bean
    public AutoConfBean autoConfBean() {
        return new AutoConfBean("auto load + " + System.currentTimeMillis());
    }
}
1
2
3
4
5
6
7
8
9

# 3. 实例演示

在新工程中,测试前面的工程的bean,看是否可以正常加载,这一小结结合源码运行查看,更有助于理解

源码工程说明

  • 005-autoconfig 提供自动加载的Bean的工程,内部定义了前面的两个测试Bean和配置文件
  • 004-bean 测试引入第三方jar中Bean的工程

测试代码如下,已删除无关的内容

@RestController
public class DemoController {
    /**
     * 测试引入第三方包的情况
     */
    @Autowired
    private AutoBean autoBean;

    @Autowired
    private AutoConfBean autoConfBean;

    @GetMapping(path = "/show")
    public String show(String name) {
        Map<String, String> map = new HashMap<>(4);
        // ...
        map.put("auto", autoBean != null ? autoBean.getName() : "null");
        map.put("autoConf", autoConfBean != null ? autoConfBean.getName() : "null");
        return JSON.toJSONString(map);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

演示图如下:

gif.gif

# 4. 小结

本篇的内容比较简单,东西也不多,主要就是在自己的项目中添加一个Configuration配置类,然后在资源目录下新增 META-INF/spring.factories 即可

上面这么做,其实和Java本身的SPI机制有点像,都是讲一些类信息写在约定的文件中,然后由框架层来获取文件中的内容然后进行解析,后面在源码篇,会涉及到整个处理流程;现在知道大致是这么玩的就行

从简单的使用来讲,上面可以满足一般场景,但是实际的应用中,还有其他的问题

  • 我直接依赖或间接依赖了很多jar包,但是有些包并不想引入他们定义的AutoConfig怎么办?(如进行redis操作的Lettuce和Jedis,只需要一个生效即可)
  • 如我的Jar包工作的前提是需要引入其他的jar包,但是我不知道使用我的地方是否提供了这个依赖,如何处理?(如只有Spring容器中有BeanA之后,我定义的Bean才生效)
  • Bean初始化顺序的问题

# II. 其他

# 0. 相关

# a. 参考

  • 官方文档:Creating Your Own Auto-configuration (opens new window)

# b. 项目

  • 工程:spring-boot-demo (opens new window)
  • module: 004-bean (opens new window)
  • module: 005-autoconfig (opens new window)

# 1. 一灰灰Blog

  • 一灰灰Blog个人博客 https://blog.hhui.top (opens new window)
  • 一灰灰Blog-Spring专题博客 http://spring.hhui.top (opens new window)

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

# 2. 声明

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

  • 微博地址: 小灰灰Blog (opens new window)
  • QQ: 一灰灰/3302797840

# 3. 扫描关注

一灰灰blog

QrCode

知识星球

goals

编辑 (opens new window)
#Bean
上次更新: 2021/10/15, 19:56:22
【基础系列】Bean之基本定义与使用
【基础系列】Bean之动态注册

← 【基础系列】Bean之基本定义与使用 【基础系列】Bean之动态注册→

最近更新
01
【基础系列】基于maven多环境配置
04-25
02
【WEB系列】内嵌Tomcat配置Accesslog日志文件生成位置源码探索
04-24
03
【搜索系列】ES查询常用实例演示
04-18
更多文章>
Theme by Vdoing | Copyright © 2017-2022 一灰灰Blog
MIT License | 鄂ICP备18017282号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×