在写多数据源 starter 的过程中,直接命中了这里的一个小坑. 记录一波.

其实呢,也不算是坑,不过我相信绝大部分使用 SpringBoot 的同学都不太清楚这两者之间的区别.

区别

它们之间的区别不是很大,但是如果不明白的话,在自定义 Starter 的时候还是会出现一点小错误的.

功能 Configuration EnableAutoConfiguration
注入时间 优先于Enable 落后于配置(static除外)
注入方式 扫描@Configuration注解 获取spring.factories并初始化数据
注入顺序 @Order配置先后 AutoConfigureBefore
AutoConfigureAfter
等配置先后

auto-configure的目的就是让第三方jar里面的类可以很方便的添加到IOC容器里面去 如果你开发 Starter 中遇到了困难,那么得想想是不是适合用 Starter 来搞. 满不满足 方便 这两字

失败举例

在自定义多数据源 Starter 中,我使用了如下配置来定义多个数据源.

  1. raycloud.multi.datasource.datasource-properties.first.username=root
  2. raycloud.multi.datasource.datasource-properties.first.password=chenshun
  3. raycloud.multi.datasource.datasource-properties.first.url=jdbc:mysql://127.0.0.1:3306/project_manager?useUnicode=true&characterEncoding=utf-8&autoReconnect=true
  4. raycloud.multi.datasource.datasource-properties.first.base-packages=com.raycloud.test.web.first
  5. raycloud.multi.datasource.datasource-properties.first.location-pattern=classpath*:/mapper/first/*.xml
  6. #second
  7. raycloud.multi.datasource.datasource-properties.second.username=root
  8. raycloud.multi.datasource.datasource-properties.second.password=chenshun
  9. raycloud.multi.datasource.datasource-properties.second.url=jdbc:mysql://127.0.0.1:3306/sentinel?useUnicode=true&characterEncoding=utf-8&autoReconnect=true
  10. raycloud.multi.datasource.datasource-properties.second.base-packages=com.raycloud.test.web.second
  11. raycloud.multi.datasource.datasource-properties.second.location-pattern=classpath*:/mapper/second/*.xml

分别配置了 数据源 firstsecond . 使用以下的格式来进行参数接受.

  1. @ConfigurationProperties(prefix = "raycloud.multi.datasource")
  2. public class DataSourcePropertyBean {
  3. private final Map<String, PropertyBean> datasourceProperties = new HashMap<>();
  4. public Map<String, PropertyBean> getDatasourceProperties() {
  5. return datasourceProperties;
  6. }
  7. @Getter
  8. @Setter
  9. public static class PropertyBean {
  10. }
  11. }

😌

于是我兴冲冲的启动了一个web应用. 还没有写Controller.
没毛病启动成功.

😣

于是我添加了一个测试的 Controller , 并且在其中注入 FirstMapperSecondMapper . 万万没想到注入失败了.
提示需要一个 FirstMapper 但是没有找到,奇不奇怪,惊不惊喜. 在经历debug和搜索后,我可以肯定的是,web的初始化发生在Enable之前,导致starter的配置还没有初始化完成而Controller已经要初始化了,所以获取不到Mapper.
这里的问题就是没有搞明白 EnableAutoConfigurationConfiguration 的顺序, Configuration 的注入发生在 EnableAutoConfiguration 之前.

所以只要使用Configuration来进行配置,然后将mybatis和datasource注入到IOC当中, 注意这里需要将注入Bean和参数进行分离.

详细代码请参考.
SpringBoot 多数据源Starter

参考链接