首先先回顾下module与maven/gradle的关系:
module与maven/gradle是什么关系?
模块化的依赖关系,很容易让人联想到mven和gradle,这个在上篇中也提及,后来有读者也提出module和maven是什么关系?解答如下:
Maven 有两个主要的特征:依赖管理和构建管理。 依赖管理即可以决定库中的版本并从仓库中下载下来。 构建管理即管理开发过程中的任务,包括初始化、编译、测试、打包等。
Module是系统内置用于表述组件之间的关系,对于版本的管理还是处于最原始的状体,管理一种强制的依赖关系。
总结一下:Maven还是主要负责构建管理,Modules 对于像Maven这样的构建工具(build tools)来说扮演的是辅助补充的角色。因为这些构建工具在构建时建立的依赖关系图谱和他们版本可以根据Module来创建,Module强制确定了module和artifacts之间的依赖关系,而Maven对于依赖并非是强制的。 具体可参考StackOverflow上的一篇问答:Project Jigsaw vs Maven on StackOverflow
说到starter,如果用过SpringBoot的开发者可能很熟悉,Starter主要用来简化依赖用的。
Starter是什么?
Starter主要用来简化依赖用的
- Starter前时代
在Starter之前做MVC时要引入日志组件,比如log4j,那么需要找到依赖的log4j的版本,有的时候版本不匹配也会出现问题,因为我们也不知道依赖什么版本,那么Starter就应运而生。
- Starter
我们要在SpringBoot中引入WebMVC的支持时,我们只需引入这个模块spring-boot-starter-web,有了Starter之后,log4j就自动引入了,也不用关心版本这些问题,将这个模块如果解压包出来会发现里面什么都没有,只定义了一些POM依赖,所以说Starter的作用主要是简化依赖。
- SpringBoot Starters
《Spring Boot in Action》
的附录B列出了SpringBoot Starters的内容:
Starter(Group ID: org.springframework.boot) | 传递依赖 |
---|---|
spring-boot-starter-web | org.springframework.boot:spring-boot-starter org.springframework.boot:spring-boot-starter-tomcat org.springframework.boot:spring-boot-starter-validation com.fasterxml.jackson.core:jackson-databind org.springframework:spring-web org.springframework:spring-webmvc |
spring-boot-starter-log4j2 | org.apache.logging.log4j:log4j-slf4j-impl org.apache.logging.log4j:log4j-api org.apache.logging.log4j:log4j-core org.slf4j:jcl-over-slf4j org.slf4j:jul-to-slf4j |
... | .... |
如何定义自己的Starter?
- 基于已有starter进行扩展(pom.xml)
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 添加依赖 -->
<dependencies>
<!-- 自动配置依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>1.5.2.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies>
复制代码
- 定义自动配置配置类
package net.hellomypastor.springboot.starter;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix="dog.proterties")
public class DogProperties {
private String name;
private int age;
//set、get
}
复制代码
package net.hellomypastor.springboot.starter;
public class DogService {
private DogProperties dogProperties;
public DogService() {
}
public DogService(DogProperties dogProperties) {
this.dogProperties = dogProperties;
}
public String getDogName() {
return dogProperties.getName();
}
public int getDogAge() {
return dogProperties.getAge();
}
}
复制代码
package net.hellomypastor.springboot.starter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
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
@EnableConfigurationProperties(DogProperties.class)
@ConditionalOnClass(DogService.class)
@ConditionalOnProperty(prefix="dog.proterties", value="enabled", matchIfMissing=true)
public class DogAutoConfiguration {
@Autowired
private DogProperties dogProperties;
@Bean
@ConditionalOnMissingBean(DogService.class)
public DogService personService() {
DogService dogService = new DogService(dogProperties);
return dogService;
}
}
复制代码
- 修改META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=net.hellomypastor.configure.DogAutoConfiguration
复制代码
- 打包
spring官方说明定义starter时最好是按
*-spring-boot-starter
的格式进行命名
mvn clean install
复制代码
- 使用
将上述starter作为依赖,并配置application.properties:
dog.properties.name=dog2018
dog.properties.age=1
复制代码
那么在类中只要注入DogService就能获取到配置的值:
package net.hellomypastor.springboot.starter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/dog")
public class DogController {
@Autowired
private DogService dogService;
@GetMapping("name")
public String getDogName() {
return dogService.getDogName();
}
@GetMapping("age")
public int getDogAge() {
return dogService.getDogAge();
}
}
复制代码
测试请求结果:
http:127.0.0.1:8080/starterdemo/dog/name
结果:dog2018
http:127.0.0.1:8080/starterdemo/dog/age
结果:1
复制代码
好了,本期就讲到这里,下期我们讲讲Java9中到另一个新工具
JShell
,敬请期待~