在写多数据源 starter
的过程中,直接命中了这里的一个小坑. 记录一波.
其实呢,也不算是坑,不过我相信绝大部分使用 SpringBoot
的同学都不太清楚这两者之间的区别.
- EnableAutoConfiguration 开启
SpringBoot
的自动装配 - Configuration 将
@Bean
注解的方法注入到Spring
的IOC
容器中.
区别
它们之间的区别不是很大,但是如果不明白的话,在自定义 Starter
的时候还是会出现一点小错误的.
功能 | Configuration | EnableAutoConfiguration |
---|---|---|
注入时间 | 优先于Enable | 落后于配置(static除外) |
注入方式 | 扫描@Configuration注解 | 获取spring.factories并初始化数据 |
注入顺序 | @Order配置先后 | AutoConfigureBefore AutoConfigureAfter 等配置先后 |
auto-configure的目的就是让第三方jar里面的类可以很方便的添加到IOC容器里面去 如果你开发
Starter
中遇到了困难,那么得想想是不是适合用Starter
来搞. 满不满足方便
这两字
失败举例
在自定义多数据源 Starter
中,我使用了如下配置来定义多个数据源.
raycloud.multi.datasource.datasource-properties.first.username=root
raycloud.multi.datasource.datasource-properties.first.password=chenshun
raycloud.multi.datasource.datasource-properties.first.url=jdbc:mysql://127.0.0.1:3306/project_manager?useUnicode=true&characterEncoding=utf-8&autoReconnect=true
raycloud.multi.datasource.datasource-properties.first.base-packages=com.raycloud.test.web.first
raycloud.multi.datasource.datasource-properties.first.location-pattern=classpath*:/mapper/first/*.xml
#second
raycloud.multi.datasource.datasource-properties.second.username=root
raycloud.multi.datasource.datasource-properties.second.password=chenshun
raycloud.multi.datasource.datasource-properties.second.url=jdbc:mysql://127.0.0.1:3306/sentinel?useUnicode=true&characterEncoding=utf-8&autoReconnect=true
raycloud.multi.datasource.datasource-properties.second.base-packages=com.raycloud.test.web.second
raycloud.multi.datasource.datasource-properties.second.location-pattern=classpath*:/mapper/second/*.xml
分别配置了 数据源 first
和 second
. 使用以下的格式来进行参数接受.
@ConfigurationProperties(prefix = "raycloud.multi.datasource")
public class DataSourcePropertyBean {
private final Map<String, PropertyBean> datasourceProperties = new HashMap<>();
public Map<String, PropertyBean> getDatasourceProperties() {
return datasourceProperties;
}
@Getter
@Setter
public static class PropertyBean {
}
}
😌
于是我兴冲冲的启动了一个web应用. 还没有写Controller.
没毛病启动成功.
😣
于是我添加了一个测试的 Controller
, 并且在其中注入 FirstMapper
和 SecondMapper
. 万万没想到注入失败了.
提示需要一个 FirstMapper
但是没有找到,奇不奇怪,惊不惊喜. 在经历debug和搜索后,我可以肯定的是,web的初始化发生在Enable之前,导致starter的配置还没有初始化完成而Controller已经要初始化了,所以获取不到Mapper.
这里的问题就是没有搞明白 EnableAutoConfiguration
和 Configuration
的顺序, Configuration
的注入发生在 EnableAutoConfiguration
之前.
所以只要使用Configuration来进行配置,然后将mybatis和datasource注入到IOC当中, 注意这里需要将注入Bean和参数进行分离.
详细代码请参考.
SpringBoot 多数据源Starter