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. linux-mysql-install

    版本是5.6之前的,安装MySQL步骤 yum install mysql-server 安装服务器端 yum install mysql-devel 安装服务器端 mysql配置文件/etc/my. ...

  2. jquery-ui拖拽对齐线位置不对的操作

    1,在draggable的drag中直接获取$(this).offset()来给对齐线设置top和left: 2,在draggable的drag中直接获取event的clientX去和event的of ...

  3. Quartz.Net 任务调度之日志(5)

    Quartz.框架的监听器和日志 1.JobListener  任务日志 新建一个类,继承IJobListener public class CustomJobListener : IJobListe ...

  4. 【leetcode】1004. Max Consecutive Ones III

    题目如下: Given an array A of 0s and 1s, we may change up to K values from 0 to 1. Return the length of ...

  5. python学习--第三天 粗略介绍人脸识别

    首先安装opencv 在安装opencv过程中遇到一些错误(百度解决) 直接贴代码吧,讲师略讲了一下,体会不深,以后有机会深入学习,再详细介绍解释吧 人脸识别训练集应该可以网上下载吧,都是开源的 im ...

  6. Java 基础 - 自动装箱,valueOf装箱,new -->使用 == 和 equals比较

    总结 关于equals 比较  记住:equals方法比较的是真正的值 两个包装类比较,比较的是包装的基本数据类型的值 基本数据类型和包装类型比较时,会先把基本数据类型包装后再比较 (但是因为equa ...

  7. ActiveMQ消息中间件Producer和Consumer

    ActiveMQ消息中间件Producer和Consumer 原创jethai2015-08-18 18:08:56评论(0)1480人阅读   生产者代码: 1 2 3 4 5 6 7 8 9 10 ...

  8. .content和.text的区别

    python中内置库 requests的两种方法get()和post()返回的的一个对象,有两种方法.content和.text ..content返回的是字节码,.text返回的是字符串.

  9. (转)Android Studio启动AVD遇到的问题 ( HAXM安装失败)

    转:https://zhidao.baidu.com/question/561420516357269084.html?qq-pf-to=pcqq.c2c Android Studio启动虚拟机的时候 ...

  10. python pymouse用法记录

    from pymouse import PyMouse m = PyMouse() m.position()#获取当前坐标的位置 m.move(x,y)#鼠标移动到xy位置 m.click(x,y)# ...