Spring Boot Starter 介绍

http://www.baeldung.com/spring-boot-starters
做者:baeldung
译者:http://oopsguy.comjava

一、概述

依赖管理一直是复杂项目的关键部分。使用手动的方式来实现依赖管理不太现实,你得花更多时间,同时你在项目的其余方面能付出的时间就会变得越少。git

Spring Boot starter 就是为了解决这个问题而诞生的。Starter POM 是一组便捷的依赖描述符,您能够将其包含在应用程序中。您能够经过它得到所需的全部 Spring 和相关技术的一站式服务,无需专门去搜索示例代码和复制粘贴依赖。github

咱们有超过 30 个 Boot starter — 下文将介绍一部分。web

二、Web Starter

首先,让咱们来看看 REST 服务开发。咱们可使用像 Spring MVC、Tomcat 和 Jackson 这样的库,这对于单个应用程序来讲是仍是存在许多依赖。spring

Spring Boot starter 经过添加一个依赖来帮助减小手动添加依赖的数量。所以,您不要手动指定依赖,只须要添加一个 starter 便可,以下所示:sql

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

如今咱们能够建立一个 REST 控制器。为了简单起见,咱们不使用数据库,只专一于 REST 控制器:数据库

@RestController
public class GenericEntityController {
    private List<GenericEntity> entityList = new ArrayList<>();
 
    @RequestMapping("/entity/all")
    public List<GenericEntity> findAll() {
        return entityList;
    }
 
    @RequestMapping(value = "/entity", method = RequestMethod.POST)
    public GenericEntity addEntity(GenericEntity entity) {
        entityList.add(entity);
        return entity;
    }
 
    @RequestMapping("/entity/findby/{id}")
    public GenericEntity findById(@PathVariable Long id) {
        return entityList.stream().
                 filter(entity -> entity.getId().equals(id)).
                   findFirst().get();
    }
}

GenericEntity 是一个简单的 bean,id 类型为 LongvalueString 类型。json

就这样,应用程序能够开始运行了,您能够访问 http://localhost:8080/springbootapp/entity/all 并检查控制器是否正常工做。springboot

咱们已经建立了一个配置很是少的 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-artifact 的版本。若是之后您想要升级 Boot 库和依赖,只需在这个地方升级 Boot 版本便可,它将会处理其他依赖的版本信息。

让咱们来测试一下以前建立的控制器。

测试控制器有两种方法:

  • 使用 mock 环境
  • 使用嵌入式 Servlet 容器(如 Tomcat 或 Jetty)

在本例中,咱们将使用一个 mock 环境:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class SpringBootApplicationTest {
    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;
 
    @Before
    public void setupMockMvc() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
 
    @Test
    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))); 
    } 
}

@WebAppConfiguration 注解和 MockMVCspring-test 模块的一部分,hasSize 是一个 Hamcrest matcher,@Before 是一个 JUnit 注解。这些均可以经过导入这个 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>

如今,应用程序已经对这些数据库已经有了开箱即用的自动支持:H二、Derby 和 Hsqldb。在示例中,咱们将使用 H2 数据库。

如今让咱们为实体建立一个仓储(repository):

public interface GenericEntityRepository extends JpaRepository<GenericEntity, Long> {}

如下是测试代码,使用 JUnit 测试:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class SpringBootJPATest {
     
    @Autowired
    private GenericEntityRepository genericEntityRepository;
 
    @Test
    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 屏蔽了这些复杂逻辑 — mail 依赖能够作得更简单:

<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 能够在 Maven 中央仓库(http://search.maven.org/#search%7Cga%7C1%7Csubethasmtp)中找到。

如下是测试源码:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class SpringBootMailTest {
    @Autowired
    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";
 
    @Before
    public void setUp() throws Exception {
        final int TEST_PORT = 25;
        wiser = new Wiser(TEST_PORT);
        wiser.start();
    }
 
    @After
    public void tearDown() throws Exception {
        wiser.stop();
    }
 
    @Test
    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 的 email 设置能够在 application.properties 中自定义:

spring.mail.host=localhost
spring.mail.port=25
spring.mail.properties.mail.smtp.auth=false

咱们在 localhost:25 上配置了邮件服务器,不须要进行身份验证。

六、结论

在本文中,咱们介绍了 Starter,解释了为何须要它们,并提供了如何在项目中使用它们的示例。

让咱们回顾一下使用 Spring Boot starter 的好处:

  • 加强 pom 可管理性
  • 生产、测试与依赖配置支持
  • 减小项目的总体配置时间

这里(https://github.com/spring-projects/spring-boot/tree/master/spring-boot-starters)能够找到相关 starter 的列表。示例源码可从这里(https://github.com/eugenp/tutorials/tree/master/spring-boot)获取。

原文示例代码

https://github.com/eugenp/tutorials/tree/master/spring-boot

相关文章
相关标签/搜索