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

文章目录
  1. I. AutoConfiguration
    1. 1. 包路径扫描使用姿势
    2. 2. 定义Bean使用方式
    3. 3. 实例演示
    4. 4. 小结
  2. II. 其他
    1. 0. 相关
      1. a. 参考
      2. b. 项目
    2. 1. 一灰灰Blog
    3. 2. 声明
    4. 3. 扫描关注

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

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

I. AutoConfiguration

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

1. 包路径扫描使用姿势

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

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

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

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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;
}
}

2. 定义Bean使用方式

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

1
2
3
4
5
6
7
8
9
10
11
12
13
@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
@Configuration
@ComponentScan("com.git.hui.boot.autoconfig")
public class SelfAutoConfig {

@Bean
public AutoConfBean autoConfBean() {
return new AutoConfBean("auto load + " + System.currentTimeMillis());
}
}

3. 实例演示

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

源码工程说明

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@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);
}
}

演示图如下:

gif.gif

4. 小结

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

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

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

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

II. 其他

0. 相关

a. 参考

b. 项目

1. 一灰灰Blog

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

2. 声明

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

3. 扫描关注

一灰灰blog

QrCode

知识星球

goals


打赏 如果觉得我的文章对您有帮助,请随意打赏。
分享到