SpringBoot 开发随笔
Spring Boot 配置
邮件发送
在本地开发环境测试,Spring Boot 能够正常发送邮件,但部署到阿里云 ECS 服务器以后,一直没有收到邮件,部分关键日志信息如下:
1 | org.springframework.mail.MailSendException: Mail server connection failed; nested exception is com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.163.com, 25; timeout -1; |
从现有情况看,跟程序运行环境有关,查看相关资料,发现在阿里云 ECS 服务器上,默认禁用了 25 端口,所以在通过 25 端口去连接邮件服务器时,无法连上,就报超时了。官方建议使用 465 端口,而 456 端口是 SSL 协议的,所以不仅要换端口,还需要进行 SSL 协议替换。下面是在 application.properties
进行的邮件发送相关配置,经过这样配置后,在阿里 ECS 上就能够正常发送邮件了
1 | # Mail Config |
163 邮箱相关服务器信息如下:
bootstrap.yml 与 application.yml 的区别
加载顺序
bootstrap.yml
>application.yml
>application-dev.yml
bootstrap.yml
作用于应用程序上下文的引导阶段,bootstrap.yml
由父 Spring ApplicationContext 加载- 若
bootstrap.yml
和application.yml
在同一目录下时,bootstrap.yml
先加载,application.yml
后加载 - 若
application.properties
和application.yml
在同一目录下时,且存在相同的配置,则application.properties
会覆盖application.yml
里面的属性,因为application.properties
会后加载,也就是说哪个文件被最后加载,哪个才具有最高级
配置区别
bootstrap.yml
和application.yml
都可以用来配置参数bootstrap.yml
用来程序引导时执行,应用于更加早期配置信息读取,可以理解成系统级别的一些参数配置,这些参数一般是不会变动的,一旦bootStrap.yml
被加载,则内容不会被覆盖application.yml
用来定义应用级别的配置参数,即应用程序特有的配置信息,可以用来配置后续各个模块中需使用的公共参数等。如果加载的application.yml
的内容标签与bootstrap.yml
的标签一致,那么application.yml
会覆盖bootstrap.yml
, 而application.yml
里面的内容可以动态替换
典型应用场景
- 一些加密 / 解密的场景
- 一些固定的不能被覆盖的属性
- 当使用 Spring Cloud Config Server 的时候,应该在
bootstrap.yml
里面指定spring.application.name
和spring.cloud.config.server.git.uri
。这是因为当使用 Spring Cloud 的时候,配置信息一般是从 Config Server 加载的,为了取得配置信息(比如密码等),需要一些提早的或引导配置。因此,把 Config Server 信息放在bootstrap.yml
,用来加载真正需要的配置信息。
扫描父模块的 Mapper 类与 XML 映射文件
子模块若希望扫描到父模块里 MyBatis 的 Mapper 类与 XML 映射文件,需要加入以下配置:
- 在主启动类上指定 Mapper 扫描的包名,父模块的包名命名规则必须符合
com.shop.**.mapper
规则
1 |
|
- 在 MyBatis-Plus 的配置中,指定 XML 映射文件的扫描路径,同时指定 MyBatis 的类型别名扫描规则
1 | mybatis-plus: |
Spring Boot 单元测试
基础使用
引入 Maven 依赖
1 | <parent> |
添加 @RunWith
、@SpringBootTest
注解
1 |
|
其中有两个 runner
可以选择,分别是 SpringRunner
和 SpringJUnit4ClassRunner
。如果是在 Junit 4.3 之前,只能选择 SpringJUnit4ClassRunner
,如果是 Junit 4.3 之后,建议选择 SpringRunner
,其中 SpringRunner
仅仅继承了 SpringJUnit4ClassRunner
,没有任何的额外代码。
1 |
|
注解说明
- @RunWith:标识为 JUnit 的运行环境
- @SpringBootTest:获取启动类、加载配置,确定装载 Spring Boot
- @Test:声明需要测试的方法
- @BeforeClass:针对所有测试,只执行一次,且必须被 static void 修饰
- @AfterClass:针对所有测试,只执行一次,且必须被 static void 修饰
- @Before:每个测试方法运行前都会执行的方法
- @After:每个测试方法运行后都会执行的方法
- @Ignore:忽略方法
断言测试
断言测试也就是期望值测试,是单元测试的核心,也就是决定测试结果的表达式,Assert 对象中的断言方法如下:
- Assert.assertEquals:对比两个值相等
- Assert.assertNotEquals:对比两个值不相等
- Assert.assertSame:对比两个对象的引用相等
- Assert.assertArrayEquals:对比两个数组相等
- Assert.assertTrue:验证返回是否为真
- Assert.assertFlase:验证返回是否为假
- Assert.assertNull:验证 Null
- Assert.assertNotNull:验证非 Null
超时测试
给 @Test
注解设置 timeout
属性即可,时间单位为毫秒:
1 | @Test(timeout = 1000) |
数据库测试
在测试数据操作的时候,若不想让测试数据污染数据库,只需要给测试类或者测试方法添加 @Transactional
注解即可,这样既可以测试数据操作方法,又不会污染数据库,即默认会回滚对数据库的所有写操作。
1 |
|
Web 模拟测试
在 Spring Boot 项目里面可以直接使用 Junit 对 Web 项目进行测试,Spring 提供了 TestRestTemplate
对象,使用这个对象可以很方便的进行请求模拟。
Web 测试只需要进行两步操作:
- 在
@SpringBootTest
注解上设置webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
,即使用随机端口 - 使用
TestRestTemplate
类进行 POST 或 GET 请求
1 |
|
其中 getForObject()
的含义代表执行 GET 请求,并返回 Object
类型的结果,第二个参数表示将返回结果转换为 String
类型,更多的请求方法如下:
- getForEntity:Get 请求,返回实体对象(可以是集合)
- postForEntity:Post 请求,返回实体对象(可以是集合)
- postForObject:Post 请求,返回对象