Skip to content
Xiaoyu's Blog
Go back

编写starter的正确方式以及感悟

一、遇到的问题

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

@Configuration
@Sl4j
public class BeanRegisterConfiuration{

		@Bean
		public BeanRegister beanRegister(){
				log.info("BeanRegisterConfiuration be loaded...");
				return new BeanRegister();
		}
}
public class BeanRegister{
	
		private String name;

}

2、新建项目 bean-starter-test 包名:fun.pxyc.beanstartertest

Maven pom.xml引入bean-starter依赖

@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文件的

参考文档

SpringBoot--自定义SpringBootStarter

架构杂谈:JAVA包命名设计


Share this post:

Previous Post
Redis设计与实现(第一部分 数据结构 )
Next Post
Maven多模块下依赖引用问题