简介
springboot 最重要的作用就是自动装配, 将某个需要人工手动创建的Bean自动注入到Spring容器中, 这里我们通过一个很简答的例子来演示
- mrathena.jar: 一个工具包, 提供了一个叫做Mrathena的短信发送服务, 我们可以在工程中引入该jar, 将Mrathena配置成一个Bean来使用
- mrathean-spring-boot-starter.jar: mrathena.jar的自动装配starter, 在springboot项目中可以自动注册Mrathena这个Bean
- demo工程: 演示效果的springboot工程
mrathean
非常简单的一个Maven工程, 只有一个工具类, 模拟短信发送服务类
package com.mrathena;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
@Setter
public class Mrathena {
/**
* SMS服务商提供的授权Key
*/
private String key;
/**
* 模拟发送短信服务
*/
public boolean send(String mobile, String content) {
try {
// 组装请求
Map<String, String> request = new HashMap<>();
request.put("key", key);
request.put("mobile", mobile);
request.put("content", content);
// 发送请求
// 处理响应
// 返回结果
return "zxcvbnm.".equals(request.get("key"));
} catch (Throwable cause) {
throw new RuntimeException(cause);
}
}
}
mrathena-spring-boot-starter
自定义的starter工程
- mrathena-spring-boot: 父模块
- mrathena-spring-boot-autoconfigure: 自动装配模块
- mrathena-spring-boot-starter: starter模块
工程结构
pom.xml (mrathena-spring-boot)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mrathena.spring.boot</groupId>
<artifactId>mrathena-spring-boot</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modules>
<module>mrathena-spring-boot-autoconfigure</module>
<module>mrathena-spring-boot-starter</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.mrathena.spring.boot</groupId>
<artifactId>mrathena-spring-boot-autoconfigure</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.mrathena.spring.boot</groupId>
<artifactId>mrathena-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
pom.xml (mrathena-spring-boot-autoconfigure)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mrathena-spring-boot</artifactId>
<groupId>com.mrathena.spring.boot</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mrathena-spring-boot-autoconfigure</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 导入配置文件处理器, 配置文件和对应的配置类进行绑定后, 在 application.properties 等配置文件里就会有提示 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- 假装的自动装配的工具类Mrathena -->
<dependency>
<groupId>com.mrathena.spring.boot</groupId>
<artifactId>mrathena</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
pom.xml (mrathena-spring-boot-starter)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mrathena-spring-boot</artifactId>
<groupId>com.mrathena.spring.boot</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mrathena-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.mrathena.spring.boot</groupId>
<artifactId>mrathena-spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
</project>
MrathenaAutoConfiguration.java
package com.mrathena.spring.boot.starter.autoconfigure;
import com.mrathena.Mrathena;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
// 引入该starter的工程的配置文件中必须包含 mrathena.enable=true, 该自动装配才会生效
@ConditionalOnProperty(prefix = "mrathena", name = "enable", havingValue = "true", matchIfMissing = false)
// 启用 MrathenaProperties 和 配置文件 的自动绑定
// 会从 引入该starter的工程的配置文件中 将 对应的配置项 赋值到 MrathenaProperties的对应字段中
@EnableConfigurationProperties(MrathenaProperties.class)
public class MrathenaAutoConfiguration {
@Autowired
private MrathenaProperties properties;
@Bean
// 当引入该starter的工程的spring容器中没有Mrathena.class类型的Bean时, 该配置项生效, 会自动注册一个Mrathena的Bean
@ConditionalOnMissingBean(Mrathena.class)
public Mrathena mrathena() {
Mrathena mrathena = new Mrathena();
mrathena.setKey(properties.getKey());
return mrathena;
}
}
MrathenaProperties.java
package com.mrathena.spring.boot.starter.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
// 将前缀为 mrathena 的配置项绑定到该配置类
@ConfigurationProperties("mrathena")
public class MrathenaProperties {
private Boolean enable;
private String key;
public Boolean getEnable() {
return enable;
}
public void setEnable(Boolean enable) {
this.enable = enable;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
META-INF/spring.factories
# 让 SpringBoot 工程启动的时候可以读取到 自动装配配置类 MrathenaAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mrathena.spring.boot.starter.autoconfigure.MrathenaAutoConfiguration
demo
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mrathena</groupId>
<artifactId>demo</artifactId>
<version>1.0.0</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 引入自定义的 mrathena-spring-boot-starter -->
<dependency>
<groupId>com.mrathena.spring.boot</groupId>
<artifactId>mrathena-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application.java
package com.mrathena.demo;
import com.mrathena.Mrathena;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import javax.annotation.PostConstruct;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired(required = false)
private Mrathena mrathena;
// 工程启动后将自动运行 run 方法
@PostConstruct
public void run() {
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> {
// 如果存在 mrathena 这个Bean, 则打出对象, 否则打出null
System.out.println(mrathena);
if (null != mrathena) {
// 如果存在Bean, 则调用其send方法
System.out.println(mrathena.send("123456789", "恭喜您收获二等奖"));
}
}, 1, 1, TimeUnit.SECONDS);
}
}
测试
暂不配置 mrathena.enable=true
application.properties
# SpringBoot工程启动时可以打印出各自动装配配置类是否生效的信息
debug=true
执行结果
2021-03-26 21:09:12.574 INFO 11812 --- [ main] com.mrathena.demo.Application : Started Application in 0.622 seconds (JVM running for 1.073)
null
null
null
null
自动装配配置类是否生效
MrathenaAutoConfiguration:
Did not match:
- @ConditionalOnProperty (mrathena.enable=true) did not find property 'enable' (OnPropertyCondition)
配置 mrathena.enable=true
# SpringBoot工程启动时可以打印出各自动装配配置类是否生效的信息
debug=true
# mrathena-spring-boot-autoconfigure 中依赖了 spring-boot-configuration-processor
# 在配置文件和对应的配置类进行绑定后, 即可提示自定义配置项
mrathena.enable=true
mrathena.key=zxcvbnm.
执行结果
2021-03-26 21:13:33.879 INFO 11200 --- [ main] com.mrathena.demo.Application : Started Application in 0.621 seconds (JVM running for 1.023)
com.mrathena.Mrathena@2442c9e0
true
com.mrathena.Mrathena@2442c9e0
true
自动装配配置类是否生效
MrathenaAutoConfiguration matched:
- @ConditionalOnProperty (mrathena.enable=true) matched (OnPropertyCondition)