好久没有更新博客了,今天来记录一下starter的内部依赖原理,并自定义一个starter
starter是个啥,之前我的博客中已经反复提到了,简单来看它是一个场景启动器,一个又一个starter包含了我们所需要的一系列依赖。我们只需要导入它,剩下的一系列maven依赖&各种组件的配置等等,都不需要我们的担心了。
这是为什么呢?
首先先来看看,每个starter内部都会或多或少依赖于别的maven座标,比如spring-boot-starter-jdbc
这个场景启动器,它内部依赖于:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.6.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
主要依赖于jdbc
、hikariCP数据源
、spring-boot-starter
,最后面的这个spring-boot-starter
是每个starter都会依赖到的,而前面两个是数据库操作时所需要用到的。
由此可以看出每个starter内部所依赖的maven座标都不尽相同,starter在这里扮演一个"调用者"的角色,负责把其他的所依赖jar
包导入进来,如果我们要自定义的话,我们可以根据要应用到的场景从而导入jar
包。
而在现实的开发中,我们自定义的starter
不仅要完成依赖导入的功能,还要做自动配置组件的工作,就是编写一个自动配置类。这个往往是我们在另外编写一个自动配置模块(和自定义starter不在同一个模块中),之后我们自定义的starter依赖于编写的自动配置模块即可。
现在开始编写代码(starter的pom文件):
<?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.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<!--启动器-->
<dependencies>
<!--引入自动配置模块-->
<dependency>
<groupId>com.leslie.starter</groupId>
<artifactId>leslie-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
自动配置模块的pom文件:
<?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.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>atguigu-spring-boot-starter-autoconfigurer</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--引入spring-boot-starter;所有starter的基本配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
因为不需要太多功能,所以自动配置模块只引入了一个spring-boot-starter
,前期的maven依赖搞定后,我们需要编写一个自动配置类,来帮容器中自动配置组件
该方法需要几个步骤:
- 编写一个xxxProperties,并使用
@ConfigurationProperties
来绑定到全局配置文件。 - 编写一个方法,该方法可以根据全局配置文件所配置的属性值来完成某些功能。
- 编写一个自动配置类(重点),在内部调用2编写的方法,并使用
@Bean
注解加入到容器中。想要让自动配置类生效,之前的博客记录过自动配置的原理,需要帮我们编写的自动配置类放到项目下的META-INF/spring.factories
目录下,类似
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
你自己编写的自动配置类的全限定类名,\
我们就来编写个简单的功能,HelloProperties:
@ConfigurationProperties(prefix = "leslie.hello") //绑定到配置文件中
public class HelloProperties {
private String prefix;
private String suffix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}
编写一个方法,用于返回配置文件中所配置的属性:
public class HelloService {
HelloProperties helloProperties;
public HelloProperties getHelloProperties() {
return helloProperties;
}
public void setHelloProperties(HelloProperties helloProperties) {
this.helloProperties = helloProperties;
}
public String sayHellAtguigu(String name){
return helloProperties.getPrefix()+"-" +name + helloProperties.getSuffix(); //调用该方法可以返回字符串
}
}
之前的做完了,接下来我们需要让编写的HelloService
类生效,我们编写一个自动配置类
@Configuration
@ConditionalOnWebApplication //web应用才生效
@EnableConfigurationProperties(HelloProperties.class) //让Helloproperties生效
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties;
//将HelloService注册到容器中
@Bean
public HelloService helloService(){
HelloService service = new HelloService();
service.setHelloProperties(helloProperties);
return service;
}
}
最后再把HelloServiceAutoConfiguration
配置到META-INF/spring.factories
即可:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.leslie.starter.HelloServiceAutoConfiguration,\
之后在编写一个Controller
来测试一下既可,这里略过。
记得有点杂乱,但还是很感谢你们的观看🙏