声明
这个系列文章是翻译自https://www.baeldung.com/的系列博客,个人感觉是一个非常不错的Spring Boot 教程。原网站属于一个公司,主要开展有偿培训业务,但提供相关文字教程的免费阅读和下载。因为我并没有在网页找到相关版权描述信息,所以并不能确定是否可以自由翻译和转载,如果有版权问题,请联系我,我会撤下这个系列文章。
原文地址:
因为版权的关系,本文禁止转载。
概述
依赖关系管理是任何复杂项目的关键方面。而手动执行此操作并不理想;你花在它上面的时间越多,你在项目的其他重要方面的时间就越少。
Spring Boot starters就是为了解决这个问题而构建的。Starter POM是一组方便的依赖项描述符,您可以将其包含在应用程序中。您可以获得所需的所有Spring和相关技术的一站式服务,而无需搜索示例代码和复制粘贴依赖描述符。
我们有超过30个Boot Starter——让我们在下面的部分中看到其中的一些。
Web Starter
首先,让我们看看如何开发REST服务;我们可以使用像Spring MVC,Tomcat和Jackson这样的库-一个应用程序有很多依赖项。
Spring Boot Starter可以通过添加一个依赖项来帮助减少手动添加依赖项的数量。因此,无需手动指定依赖项,只需添加一个starter,如以下示例所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
现在我们可以创建一个REST控制器。为了简单起见,我们将不使用数据库,而专注于REST控制器:
public class GenericEntityController {
private List<GenericEntity> entityList = new ArrayList<>();
"/entity/all")
( public List<GenericEntity> findAll() {
return entityList;
}
value = "/entity", method = RequestMethod.POST)
( public GenericEntity addEntity(GenericEntity entity) {
entityList.add(entity);
return entity;
}
"/entity/findby/{id}")
( public GenericEntity findById( Long id) {
return entityList.stream().
filter(entity -> entity.getId().equals(id)).
findFirst().get();
}
}
GenericEntity 是一个简单的bean,id类型为Long,value类型为String。
就是这样——在应用程序运行时,您可以访问 并检查控制器是否工作。
我们已经创建了一个REST应用程序,配置非常少。
Test Starter
为了测试,我们通常使用以下一组库:Spring Test、JUnit、Hamcrest和Mockito。我们可以手动包含所有这些库,但Spring Boot starter可以通过以下方式自动包含这些库:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
注意,您不需要指定工件的版本号。Spring Boot 将确定使用哪个版本——您需要指定的只是spring-boot-starter-parent工件的版本。如果稍后您需要升级Boot库和依赖项,只需在一个地方升级引导版本,它将负责其余部分。
让我们实际测试我们在上一个示例中创建的控制器。
有两种方法可以测试控制器:
-
使用模拟环境
-
使用嵌入式Servlet容器(如Tomcat或Jetty)
在这个例子中,我们将使用一个模拟环境:
SpringJUnit4ClassRunner.class)
(classes = Application.class)
(
public class SpringBootApplicationIntegrationTest {
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
public void setupMockMvc() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
public void givenRequestHasBeenMade_whenMeetsAllOfGivenConditions_thenCorrect()
throws Exception {
MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
mockMvc.perform(MockMvcRequestBuilders.get("/entity/all")).
andExpect(MockMvcResultMatchers.status().isOk()).
andExpect(MockMvcResultMatchers.content().contentType(contentType)).
andExpect(jsonPath("$", hasSize(4)));
}
}
上面的测试调用了/entity/all端点,并验证了JSON响应包含4个元素。为了通过这个测试,我们还必须在控制器类中初始化我们的列表:
public class GenericEntityController {
private List<GenericEntity> entityList = new ArrayList<>();
{
entityList.add(new GenericEntity(1l, "entity_1"));
entityList.add(new GenericEntity(2l, "entity_2"));
entityList.add(new GenericEntity(3l, "entity_3"));
entityList.add(new GenericEntity(4l, "entity_4"));
}
//...
}
这里重要的是 @WebAppConfiguration 注解和MockMVC是spring-test模块的一部分,hasSize是Hamcrest matcher, @Before 是JUnit annotation。这些都可以通过导入这个 starter 依赖项来获得。
Data JPA Starter
大多数Web应用程序都有某种持久性——通常是JPA。
与其手动定义所有相关的依赖项,不如使用starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
请注意,开箱即用,我们至少可以自动支持以下数据库:H2、Derby和Hsqldb。在我们的例子中,我们将使用H2。
现在,让我们为我们的实体创建存储库:
public interface GenericEntityRepository extends JpaRepository<GenericEntity, Long> {}
是时候测试代码了。下面是JUnit测试:
SpringJUnit4ClassRunner.class)
(classes = Application.class)
(public class SpringBootJPATest {
private GenericEntityRepository genericEntityRepository;
public void givenGenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
GenericEntity genericEntity =
genericEntityRepository.save(new GenericEntity("test"));
GenericEntity foundedEntity =
genericEntityRepository.findOne(genericEntity.getId());
assertNotNull(foundedEntity);
assertEquals(genericEntity.getValue(), foundedEntity.getValue());
}
}
我们没有花时间指定数据库供应商、URL连接和凭据。没有额外的配置是必要的,因为我们受益于固定的Boot默认值;但是当然如果需要,所有这些细节仍然可以被配置。
Mail Starter
企业开发中一个非常常见的任务是发送电子邮件,直接处理Java Mail API通常很困难。
Spring Boot starter隐藏了这种复杂性——可以通过以下方式指定邮件依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
现在我们可以直接使用 JavaMailSender 了,所以让我们写一些测试。
为了测试的目的,我们需要一个简单的SMTP服务器。在本例中,我们将使用Wiser。这就是我们如何将其包含在POM中:
<dependency>
<groupId>org.subethamail</groupId>
<artifactId>subethasmtp</artifactId>
<version>3.1.7</version>
<scope>test</scope>
</dependency>
最新版本的Wiser可以在中找到。
下面是测试的源代码:
SpringJUnit4ClassRunner.class)
(classes = Application.class)
(public class SpringBootMailTest {
private JavaMailSender javaMailSender;
private Wiser wiser;
private String userTo = "user2@localhost";
private String userFrom = "user1@localhost";
private String subject = "Test subject";
private String textMail = "Text subject mail";
public void setUp() throws Exception {
final int TEST_PORT = 25;
wiser = new Wiser(TEST_PORT);
wiser.start();
}
public void tearDown() throws Exception {
wiser.stop();
}
public void givenMail_whenSendAndReceived_thenCorrect() throws Exception {
SimpleMailMessage message = composeEmailMessage();
javaMailSender.send(message);
List<WiserMessage> messages = wiser.getMessages();
assertThat(messages, hasSize(1));
WiserMessage wiserMessage = messages.get(0);
assertEquals(userFrom, wiserMessage.getEnvelopeSender());
assertEquals(userTo, wiserMessage.getEnvelopeReceiver());
assertEquals(subject, getSubject(wiserMessage));
assertEquals(textMail, getMessage(wiserMessage));
}
private String getMessage(WiserMessage wiserMessage)
throws MessagingException, IOException {
return wiserMessage.getMimeMessage().getContent().toString().trim();
}
private String getSubject(WiserMessage wiserMessage) throws MessagingException {
return wiserMessage.getMimeMessage().getSubject();
}
private SimpleMailMessage composeEmailMessage() {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(userTo);
mailMessage.setReplyTo(userFrom);
mailMessage.setFrom(userFrom);
mailMessage.setSubject(subject);
mailMessage.setText(textMail);
return mailMessage;
}
}
在测试中, @Before 和 @After 方法负责启动和停止邮件服务器。
请注意,我们正在连接 JavaMailSender bean —— 该bean是由Spring Boot 自动创建的。
就像Boot中的任何其他默认设置一样,JavaMailSender 的电子邮件设置可以在 application.properties 中自定义:
spring.mail.host=localhost
spring.mail.port=25
spring.mail.properties.mail.smtp.auth=false
所以我们在 localhost:25 上配置了邮件服务器,我们不需要身份验证。
结论
在本文中,我们概述了Starters,解释了为什么我们需要它们,并提供了如何在项目中使用它们的示例。
让我们回顾一下使用Spring Boot starters的好处:
-
提高POM可管理性
-
生产就绪、测试和支持的依赖配置
-
减少项目的总体配置时间
实际的starters列表可以在找到。示例的源代码可以在
文章评论