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

相關文章
相關標籤/搜索