介绍 Spring Boot Starter

介绍 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列表可以在这里查找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值