1.概述

依赖管理是任何复杂项目的关键方面。手动完成这些操作并不理想; 你花在它上面的时间越多,你在项目的其他重要方面所花费的时间就越少。

构建Spring Boot启动器是为了解决这个问题。Starter POM是一组方便的依赖描述符,您可以在应用程序中包含这些描述符。您可以获得所需的所有Spring和相关技术的一站式服务,而无需搜索示例代码,并复制粘贴依赖描述符。

2.The Web Starter
首先,我们来看看开发REST服务; 我们可以使用像Spring MVC,Tomcat和Jackson这样的库 - 对于单个应用程序来说有很多依赖关系。

Spring Boot启动器可以通过添加一个依赖项来帮助减少手动添加的依赖项的数量。因此,不是手动指定依赖项,而是添加一个启动器,如以下示例所示:

<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,包含与Long类型id属性和String类型的value属性。

在应用程序运行时,您可以访问http://localhost:8080/entity/all 并检查控制器是否正常工作。

我们已经创建了一个具有相当小配置的REST应用程序。

3.The 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>

请注意,您无需指定artifact的版本号。Spring Boot将确定要使用的版本 - 您需要指定的是spring-boot-starter-parent的版本。如果以后需要升级Boot库和依赖项,只需在一个地方升级Boot版本,它将负责其余的工作。

让我们实际测试我们在前一个例子中创建的控制器。

有两种方法可以测试控制器:

使用模拟环境
使用嵌入式Servlet容器(如Tomcat或Jetty)
在这个例子中,我们将使用模拟环境:

@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个元素。要通过此测试,我们还必须在控制器类中初始化我们的列表:

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注释。这些都可以通过导入这一个启动器依赖项来获得。

4. The Data JPA Starter
大多数Web应用程序都有需要某种持久性 - 这通常是JPA。

不需要手动定义所有相关的依赖项 - 让我们改为使用启动器:

<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测试:

@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默认值中受益; 但当然,如有必要,仍可配置所有这些细节。

5.The Mail Starter
企业开发中一个非常常见的任务是发送电子邮件,直接处理Java Mail API通常很困难。

Spring Boot启动程序隐藏了这种复杂性 - 可以通过以下方式指定邮件依赖项:

<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>

可以在Maven中央存储库中找到最新版本的Wiser 。

以下是测试的源代码:

@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的电子邮件设置可以在application.properties中自定义:

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

我们在localhost:25上配置了邮件服务器,并且不需要身份验证。

spring boot 四大组件之Starter的更多相关文章

  1. spring boot 四大组件之Auto Configuration

    SpringBoot 自动配置主要通过 @EnableAutoConfiguration, @Conditional, @EnableConfigurationProperties 或者 @Confi ...

  2. spring boot 四大组件之Actuator

    执行器(Actuator)的定义 执行器是一个制造业术语,指的是用于移动或控制东西的一个机械装置,一个很小的改变就能让执行器产生大量的运动.An actuator is a manufacturing ...

  3. Spring Boot中如何自定义starter?

    Spring Boot starter 我们知道Spring Boot大大简化了项目初始搭建以及开发过程,而这些都是通过Spring Boot提供的starter来完成的.品达通用权限系统就是基于Sp ...

  4. Spring Boot相关组件的添加

    在勾选相关组件后, pom.xml文件上发生了根本的变化 1.这是最简单的项目的pom文件 <?xml version="1.0" encoding="UTF-8& ...

  5. 集成 Spring Boot 常用组件的后台快速开发框架 spring-boot-plus 国

    spring-boot-plus是一套集成spring boot常用开发组件的后台快速开发框架 Purpose 每个人都可以独立.快速.高效地开发项目! Everyone can develop pr ...

  6. Spring Boot必备技能之Starter自定义

    本文摘自于<Spring Cloud微服务 入门 实战与进阶>一书.  作者:尹吉欢 Spring Boot的方便体现在简化了很多繁琐的配置,对开发人员来说是一个福音,通过引入各种Spri ...

  7. Spring Boot 自动扫描组件

    使用@ComponentScan自动扫描组件 案例准备 1.创建一个配置类,在配置类上添加 @ComponentScan 注解.该注解默认会扫描该类所在的包下所有的配置类,相当于之前的 <con ...

  8. Spring Boot 整合Mybatis非starter时,mapper一直无法注入解决

    本来呢,直接使用mybatis-spring-boot-starter还是挺好的,但是我们系统比较复杂,有多个数据源,其中一个平台自己的数据源,另外一些是动态配置出来的,两者完全没有关系.所以直接使用 ...

  9. Spring boot 开发组件

    一.Jboot 描述:Jboot是一个基于jfinal 和 undertow开发的微服务框架.提供了AOP.RPC.分布式缓存.限流.降级.熔断.统一配置中心.swagger api自动生成.Open ...

随机推荐

  1. 一个故事讲懂vue父子组件传值

    作者:李佳明同学链接:https://www.jianshu.com/p/2272b6ca0f0c 一个故事讲懂vue父子组件传值 讲故事前先讲代码 父组件向子组件传值 父组件数据传递给子组件可以通过 ...

  2. 深入理解TCP协议及其源代码

    本次实验,我们来探究connect及bind.listen.accept背后的三次握手. 实验原理 首先简要回顾一下TCP三次握手的过程: 第一次握手:client向server发送SYN=1的数据报 ...

  3. solaris系统动态查看swap的使用情况

    root@tt # root@tt # prstat  -aPlease wait... PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU ...

  4. tomcat manager 禁止外网访问 只容许内网访问

    参考:http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html A default Tomcat installation includes ...

  5. python中map的排序以及取出map中取最大最小值

    map排序: 1.按key排序: items=dict.items() items.sort() sorted(dict.items(),key=lambda x:x[0],reverse=False ...

  6. WebDriverAgent安装

    这次安装WebDriverAgent的过程可谓坎坷呀,最后还是大牛远程解决问题,自己的确差太远,记录一下过程吧 尽量升级Xcode到最新版,保持iPhone的版本大于9.3 终端进入目标文件夹WebD ...

  7. Laravel 事务中使用悲观锁

    laravel 提供了方便快捷的数据库事务使用方式,在使用中遇到过几个容易混淆和被误导的地方,这里做个记录,希望哪里写的不对的地方各位大神指点一下 laravel 事务分为手动方式和自动方式. 但如果 ...

  8. django更换默认数据库sqlite3为pymsql后出现Keyerror:255的解决办法----升级PyMySQL

    一.更换数据库的办法: 1.安装PyMySQL 2.修改project目录同名文件下的settings.py:DATABASES = { 'default': { # 'ENGINE': 'djang ...

  9. (转)Android Studio解决unspecified on project app resolves to an APK archive which is not supported

    出现该问题unspecified on project app resolves to an APK archive which is not supported as a compilation d ...

  10. MySQL 5.7配置文件

    原文:http://www.voidcn.com/article/p-zrikccdi-hr.html # MySql5.7配置文件my.cnf设置[client]port = 3306socket ...