一、简介
spring boot 提供了大量的三方starter 供开发者使用,根据项目需求我们也可以自定义starter 供开发使用,并且有助理解spring boot 自动化配置的核心原理。
二、流程
1.新建user-starter 工程作为自定义starter
项目结构如下

pom.xml 核心如下:
引入spring boot parent 配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
</parent>
引入spring boot 核心依赖 spring-boot-starter
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
User.java
该User 对象代表starter 提供的对象,将会被注册到applicationContext 容器中
package com.test;
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
UserProperties.java
UserProperties 从项目配置文件application.properties / application.yml 中注入相关配置数据,以供设置User 对象相关属性
package com.test;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "custom-user")
public class UserProperties {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "UserProperties [name=" + name + ", age=" + age + "]";
}
}
UserAutoConfiguration.java
EnableConfigurationProperties 开启属性对象注入到ApplicationContext 容器
package com.test;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(UserProperties.class)
public class UserAutoConfiguration {
@Bean
@ConditionalOnMissingBean(User.class)
public User defaultUser(UserProperties properties) {
User user = new User();
user.setName(properties.getName());
user.setAge(properties.getAge());
return user;
}
}
EnableUser.java
项目引入该starter 后使用该注解使该starter 生效
package com.test;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.springframework.context.annotation.Import;
@Retention(RetentionPolicy.RUNTIME)
@Import(UserAutoConfiguration.class)
public @interface EnableUser {
}
2.新建test 项目
项目结构如下:

引入spring boot parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
</parent>
依赖配置如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vincent</groupId>
<artifactId>user-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
TestApplication.java
package com.vincent;
import java.util.Arrays;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import com.test.EnableUser;
import com.test.User;
@SpringBootApplication
@EnableUser
public class TestApplication {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(TestApplication.class, args);
System.out.println(Arrays.toString(ctx.getBeanDefinitionNames()));
System.out.println(ctx.getBean(User.class));
}
}
application.yml 配置
custom-user:
name: vincent
age: 26
三、测试
1.运行TestApplication

2.取消TestApplication 的@EnableUser 注解

3.作为三方starter 提供,引入项目后需要使用@Enablexxxx 注解使引入的starter 生效,稍有啰嗦的感觉,我们可以采用另一种方式使引入的starter 生效。
user-starter 项目 resources 目录新建META-INF 文件夹,并在文件夹中新建spring.factories 文件

4.META-INF/sprong.factories 配置如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.test.UserAutoConfiguration
EnableAutoConfiguration 后面写上需要自动配置的类,在starter 被项目引入后会自动配置。spring boot 官方提供的很多starter 就是采用这种方式实现自动化配置
5.运行TestApplication

四、总结
1.SpringBoot内置条件注解
@ConditionalOnBean:当SpringIoc容器内存在指定Bean的条件
@ConditionalOnClass:当SpringIoc容器内存在指定Class的条件
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在时查找指定的位置
@ConditionalOnMissingBean:当SpringIoc容器内不存在指定Bean的条件
@ConditionalOnMissingClass:当SpringIoc容器内不存在指定Class的条件
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径是否有指定的值
@ConditionalOnSingleCandidate:当指定Bean在SpringIoc容器内只有一个,或者虽然有多个但是指定首选的Bean
@ConditionalOnWebApplication:当项目是Web项目的条件
以上注解都是元注解@Conditional演变而来的
2.spring-boot-autoconfigure.jar 是spring boot 提供的一些常用自动化配置包
本文介绍了Spring Boot的自动化配置原理,通过自定义"user-starter"阐述了创建过程,包括配置pom.xml,定义User对象和UserProperties,以及UserAutoConfiguration。测试部分展示了如何在另一个项目中引入并启用starter。文章还总结了Spring Boot内置的条件注解,如@ConditionalOnBean和@ConditionalOnProperty,以及spring-boot-autoconfigure.jar的作用。
20万+

被折叠的 条评论
为什么被折叠?



