四、自写starts组件
starter组件命名规则:
SpringBoot
官方的建议是,如果是我们开发者自己开发的 starter
组件(即属于第三方组件),那么命名规范是{name}-spring-boot-starter
,而如果是 SpringBoot
官方自己开发的组件,则命名为 spring-boot-starter
-{name}`。当然,这只是一个建议,如果非不按这个规则也没什么问题,但是为了更好的识别区分,还是建议按照这个规则来命名。
pom文件中也可以修改组件名:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>lwl-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lwl-spring-boot-starter</name>
<description>lwl-spring-boot-starter</description>
<properties>
<java.version>1.8</java.version>
</properties>
4.1 需求
在properties文件中
lwl.test.name=lei
lwl.enabled=true
对于key值为lwl.test.name的值,在输出时会拼接上一个“hello,”
输出结果为:“ hello,lei”
4.2 实现starts组件
4.2.1 获取配置文件application.properties中的内容
/**
* ConfigurationProperties注解报错的两种解决办法
* 1、Component注解 作为bean注入到里面
* 2、EnableConfigurationProperties注解 使用配置类
* 注:这个报错不解决编译也不会报错,但是会显得不规范
*
*/
//@Component
@EnableConfigurationProperties(MyStartersProperties.class)
@ConfigurationProperties(
prefix = "lwl.test"
)
public class MyStartersProperties {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4.2.2 进行业务处理
public class MyStartersService {
private String name;
public MyStartersService(String name) {
this.name = name;
}
public MyStartersService() {
}
public String newStr(){
return "hello,"+this.name;
}
}
4.2.3 设置自动配置
自动配置就是连接前两个文件的桥梁
//标记为配置类
@Configuration
//classpath下只要发现有这个类,就会自动装配
@ConditionalOnClass(MyStartersService.class)
//装配的时候所使用的属性
@EnableConfigurationProperties(MyStartersProperties.class)
public class MyAutoConfigure {
@Resource
private MyStartersProperties myStartersProperties;
@Bean
@ConditionalOnMissingBean //spring上下文中没有这个类或者有很多类的时候会使用到这个注解
@ConditionalOnProperty(prefix = "lwl",value = "enabled",havingValue = "true") //当配置文件中lwl.enabled=true时有效。
public MyStartersService getStartersService(){
return new MyStartersService(myStartersProperties.getName());
}
}
注解的作用:
@ConditionalOnClass:当classpath下发现该类的情况下进行自动配置。
@EnableConfigurationProperties:使用 @ConfigurationProperties 注解的类生效。
@ConditionalOnMissingBean:它是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果而注册相同类型的bean,就不会成功,它会保证你的bean只有一个,即你的实例只有一个,当你注册多个相同的bean时,会出现异常,以此来告诉开发人员。
@ConditionalOnProperty(prefix = "yyl",value = "enabled",havingValue = "true"),
当配置文件中yyl.enabled=true时有效。
SpringBoot中的所有@Conditional注解及作用 :
@ConditionalOnBean:当容器中有指定的Bean的条件下
@ConditionalOnClass:当类路径下有指定的类的条件下
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean:当容器中没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径下是否有指定的资源
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件下
4.2.4 将自动配置文件写入到spring.factories文件中
resources下面建一个名为META-INF的Directory文件夹,创建spring.factories文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.startertest.config.MyAutoConfigure
#上面的key值是固定不变的,value值是自动配置类的包名+类名
另外常用的配置文件有两种,2.7以后的配置文件会更常用
4.2.5 修改打包信息
pom文件中的打包信息进行修改
<build>
<!--打包的信息-->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- 防止bean找不到,忽略一些不必要的信息 -->
<configuration>
<!--springboot的启动类,必须要填,否则会提示找不到主类-->
<!-- <mainClass>com.example.startertest.StartertestApplication</mainClass>-->
<skip>true</skip>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
4.2.6 修改启动类
//继承SpringBootServletInitializer后,重写他的配置方法
@SpringBootApplication
public class StartertestApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(StartertestApplication.class, args);
}
/**
* 重写方法,加载配置信息
*/
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(this.getClass());
}
}
4.2.7 清理并打包
利用Maven在生命周期中进行清理并打包
打包完成后,target下面会有一个打包好的文件
4.3 验证自写的starts组件
4.3.1 引入打包好的jar包
因为自写的jar包没有添加到maven仓库中,所以只能在子模块中进行测试,在子模块测试时可以不用打包
<!--引入自写的starts组件依赖-->
<dependency>
<groupId>com.example</groupId>
<artifactId>lwl-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
4.3.2 编写配置文件
lwl.test.name=lei
lwl.enabled=true
4.3.3 引入service验证
@RestController
public class TestController {
@Resource
private MyStartersService myStartersService;
@GetMapping("test")
public String testStarter(){
return myStartersService.newStr();
}
}
4.3.4 错误情况处理
如果在测试的文件中写了要求
lwl.test.name=lei
lwl.enabled=true
但是在访问的时候出现的结果:
hello,null
修改方法为
在编写starts组件的properties组件中按照ConditionalOnProperty注解进行配置
@Bean
@ConditionalOnMissingBean //spring上下文中没有这个类或者有很多类的时候会使用到这个注解
@ConditionalOnProperty(prefix = "lwl",value = "enabled",havingValue = "true") //当配置文件中lwl.enabled=true时有效。
public MyStartersService getStartersService(){
return new MyStartersService(myStartersProperties.getName());
}
编写
lwl.enabled=true