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. Django创建工程项目以及工作原理

    一.Django 创建工作项目 1.创建 North 工程项目 (1)使用CMD命令行,切换到指定路径 django-admin.py startproject north (2)使用pycharm创 ...

  2. RGB和十六进制转换

    1.十六进制换RGB 例:  var color = '#69ad52' let r = parseInt(“0px” + color.slice(1, 3))  //105 let g = pars ...

  3. SQL中的DQL查询语句

    目录 1. DQL:查询语句 排序查询 聚合函数 分组查询 分页查询 2. 约束 3. 多表之间的关系 4. 范式 DQL:查询语句 1. 排序查询 语法:order by 子句 order by 排 ...

  4. PHP chroot() 函数

    改变根目录: <?php// Change root directorychroot("/path/to/chroot/"); // Get current director ...

  5. iOS 109个Demo范例

    https://github.com/subdigital/nsscreencast 版权声明:本文为博主原创文章,未经博主允许不得转载.

  6. 前端每日实战:71# 视频演示如何用纯 CSS 创作一个跳 8 字型舞的 loader

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/gKNMMm 可交互视频 此视频是可 ...

  7. python如何读写EXCEL文档 (有助于自动化的参数化,用的方法是XLRD,XLWT)

    读EXCEL: import xlrd 例1, data=xlrd.open("E:\egg.xls")     # 打开xls文件 table=data.sheets()[0] ...

  8. 87、使用TensorBoard进行可视化学习

    1.还是以手写识别为类,至于为什么一直用手写识别这个例子,原因很简单,因为书上只给出了这个类子呀,哈哈哈,好神奇 下面是可视化学习的标准函数 ''' Created on 2017年5月23日 @au ...

  9. float不完整带来的IE7下的不兼容

    这种原因是因为搜索用了float:right;添加报考院校和导入文件没有用float; 解决的方法是:1.给添加报考院校和导入文件分别添加float:left;2.把搜索那部分代码写在添加报考院校和导 ...

  10. 数据可视化----matplotlib.pylot

    一.输入具体数 plt.plot([3,1,4,5,2]) #自动生成y轴 plt.ylabel("Grade") #y轴的标签 plt.savefig('test1',dpi=6 ...