一、遇到的问题
risk-self-service引入了我司的starter,但是发现自动配置并没有把bean注入,然后进入starter查看源码。
二、问题描述
发现我司自定的starter中没有spring.factors文件,没有告诉springboot应该去加载什么Configuration配置类。所以没有把bean注入。
那为什么其他项目没有问题呢?我发现risk-self-serivce的包名是有二级包名的,而其他项目是没有二级包名的。
risk-self-service : package com.sqg.riskservice;
others: package com.sqg;
初步猜测是SpringBoot在scan包时就没有扫到starter中的bean。
验证一下。
三、验证猜测
1、新建项目 bean-starter 包名:fun.pxyc.beanstarter
- BeanRegisterConfiuration.java
@Configuration
@Sl4j
public class BeanRegisterConfiuration{
@Bean
public BeanRegister beanRegister(){
log.info("BeanRegisterConfiuration be loaded...");
return new BeanRegister();
}
}- BeanRegister
public class BeanRegister{
private String name;
}2、新建项目 bean-starter-test 包名:fun.pxyc.beanstartertest
Maven pom.xml引入bean-starter依赖
- MainApplication
@SpringBootApplication
@Sl4j
public class MainApplication{
@Autowired
private BeanRegister beanRegister;
public static void main(String[] args){
SpringApplication.run(MainApplication.class);
log.info("beanRegister:{}",beanRegister):
}
}启动后,空指针异常,发现beanRegister未被注入。
3、手动改包名
将bean-starter-test 包名:fun.pxyc.beanstartertest → fun.pxyc.beanstarter
再重新启动服务,发现bean可以正常注入
4、猜想验证成功
四、解决方法
1、修改包名和starter包名一致 不推荐
2、配置包名让SpringBoot去扫描 推荐
@SpringBootApplication(scanBasePackages = "fun.pxyc.beanstarter")
@Sl4j
public class MainApplication{
@Autowired
private BeanRegister beanRegister;
public static void main(String[] args){
SpringApplication.run(MainApplication.class);
log.info("beanRegister:{}",beanRegister):
}
}
3、希望修改starter,增加spring.factors,无感知注入。推荐
五、最后
1、希望包名都能增加二级包名
我们包名的制定规则一般是使用域名来制定,而二级域名是可以标识到这个应用的具体业务。例如QQ邮箱,mail.qq.com,其对应的包名:com.qq.mail;英雄联盟,lol.qq.com,其对应的包名应该是:com.qq.lol,其子服务比如负责英雄联盟的用户服务的包名应该就是:com.qq.lol.userservice, 我们不应该害怕包名过长,唯一标识一个服务才是重要的,这样会避免很多导包时候的问题,打错误的堆栈时也看的更加清楚。
2、编写starter的正确方式是需要有spring.factors文件的
参考文档