Skip to main content
 首页 » 编程设计

介绍 Spring Boot Starter

2022年07月19日174wayfarer

介绍 Spring Boot Starter

依赖管理是任何复杂项目中的关键部分。手工实现显然是不明智的,你花时间越多,则在项目的其他重要部分时间越少。Spring Boot Starter致力于完美解决这个问题。Starter POM是包括在应用中的一组便利依赖描述。可以一站式获得所有Spring和相关技术库,无需寻找相同的代码,拷贝、粘贴需要载入的依赖描述。

Spring Boot 有超过30个Starter,本文下面介绍几个常用的Starter。

Web Starter

首先,我们看下开发Rest服务应用,需要如Spring MVC,Tomcat以及Jackson————单个应用需要的一系列依赖。

Spring Boot Starter 能帮助减少手工增加依赖量,仅需要增加一个依赖。下面请看示例:

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

现在我们可以创建REST controller,为了简单,我们没有使用数据库,并聚焦REST Controller:

@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,包括Long类型id,和String类型value。启动应用,可以访问 http://localhost:8080/entity/all 地址,检查Controller是否正常工作。我们使用最小化的配置创建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 库及其依赖,仅需要在一个地方升级Boot版本,剩下的交给它。下面我们测试上面的Controller。有两种方式测试Controller:

  • 使用mock环境
  • 使用内置Servlet容器,如tomcat 或 Jetty

下面示例使用mock环境:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = Application.class) 
@WebAppConfiguration 
public class SpringBootApplicationIntegrationTest { 
    @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)));  
    }  
} 

上面示例调用 /entity/all 地址并验证JSON响应包含4个元素。实现下面示例数据,我们需要在Controller类中初始化list:

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 匹配器,@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> 

注意,以下数据库提供了自动支持:H2、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> 

请看测试代码:

@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方法负责启动、停止mail服务。注意我们引入JavaMailSender bean————spring boot会自动创建。和其他缺省的Boot异议,JavaMailSender的email设置可以在application.properties中配置:

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

这里配置mail服务器在localhost:25,并且无需认证。

总结

本文我们概要介绍了Spring Boot Starter。解释了使用的必要性并提供示例说明如何在项目中使用它们。

下面回顾下面使用Spring Boot starter的优势:

  • 提高pom的可管理性
  • 现成的生成、测试、运行依赖配置
  • 减少项目的配置时间

实际starter列表可以在这里查找。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/84899487