SpringBoot入门到精通(三):热部署与单元测试(2021最新最易懂)
热部署与单元测试(2021最新最易懂)
有兴趣的可以先参考附录简单了解SpringBoot自动装配流程。
一.SpringBoot开发热部署
项目开发中,你是否也遇到更新配置文件信息后,必须重启项目的,否则数据不更新的问题?
Spring Boot提供了一个名为spring-boot-devtools的模块来使应用支持热部署,提高开发效率,修改后无需手动重启Spring Boot应用。使用也非常简单,在pom.xmI中加入devtools的依赖就可以了。当然,首次引入后,项目应用需要重启。否则不生效。
1 <!-- SpringBoot热部署依赖 --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-devtools</artifactId> 5 </dependency>
二.SprongBoot单元测试
对于java
开发者而言,Junit
应该无人不知了。所以SpringBoot
也是基于Junit
进行单位测试的。测试代码位置:建议在:src/test/java目录下
SpringBoot测试开发,只需要在pom中引入测试依赖即可使用,默认SpringBoot会排除低版本的Junit测试包。(SpringBoot推荐使用Junit5.x或更高版本)
JUnit中的注解测试常用注解:
@BeforeClass:针对所有测试,在每个类加载的开始和结束时运行,必须为静态方法:static void
@Before:初始化方法,执行当前测试类的每个测试方法前执行。
@Test:测试方法,在这里可以测试期望异常和超时时间
@After:释放资源,执行当前测试类的每个测试方法后执行
@AfterClass:针对所有测试,在每个类加载的开始和结束时运行,必须为静态方法:static void
@Ignore:忽略的测试方法(只在测试类的时候生效,单独执行该测试方法无效)基本不用
@RunWith:可以更改测试运行器 ,用来告诉JUnit不要使用内置的org.junit.runner.Runner进行单元测试,而应该使用指定的类做单元测试,对于Spring单元测试总是要使用 SpringRunner.class 。(一般不用)
一个单元测试类执行顺序为:
@BeforeClass –> @Before –> @Test –> @After –> @AfterClass
每一个测试方法的调用顺序为:
@Before –> @Test –> @After
1.测试案例
- 新建SpringBoot项目,默认会导入测试依赖,如果没有请手动修改pom文件导入。
1 <!-- SpringBoot测试依赖 --> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-test</artifactId> 5 <scope>test</scope> 6 <!-- 排除junit.vintage --> 7 <exclusions> 8 <exclusion> 9 <groupId>org.junit.vintage</groupId> 10 <artifactId>junit-vintage-engine</artifactId> 11 </exclusion> 12 </exclusions> 13 </dependency>
- 在src/test/java目录下新建测试类。
@SpringBootTest注解是SpringBoot自1.4.0版本开始引入的一个用于测试的注解。
1 @SpringBootTest 2 class SpringBootApplicationTests { 3 4 @Autowired 5 IDCard idcard; 6 7 @Test 8 void contextLoads() { 9 System.out.println("测试:"+idcard); 10 } 11 12 }
- 选中测试方法名,右键执行Junit Test即可。
其他的测试注解:略。自行演示!
附录
SpringBoot自动装配原理分析,这里简单将源码抠出,可以自行理解(为便于注释编辑)
Eclipse按住Ctrl见不松,鼠标左键点击注解@SpringBootApplication,查看@SpringBootApplication注解源码。
1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @SpringBootConfiguration // SpringBoot的基础配置:其引入的注解类使用了注解@Configuration,实际就是将启动类实现Spring管理 6 @EnableAutoConfiguration // 启用自动装配(自动配置) 进入看源码 7 @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), 8 @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) 9 public @interface SpringBootApplication {
1 @Target(ElementType.TYPE) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Inherited 5 @AutoConfigurationPackage // 自动配置注解包 6 @Import(AutoConfigurationImportSelector.class)// 导入自动装配选择器类(不是所有的信息都自动装配的,不使用的内容,不应该加载,由这个类实现排除),继续看源码 7 public @interface EnableAutoConfiguration {
1 public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, 2 ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered { 3 private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry(); 4 // 省略其他方法等代码 5 /** 6 * 该方法是一个获取自动装配项的方法,内部通过业务处理实现排除和选择使用的自动装配项 7 * @param annotationMetadata 是注解元数据(个人理解指的是应用中注解) 8 */ 9 protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { 10 // 判断:没有/已启用注解源数据 11 if (!isEnabled(annotationMetadata)) { 12 return EMPTY_ENTRY;// 没有启用则直接返回自动装配配置对象(到此就止了) 13 } 14 // 获取所有注解属性 15 AnnotationAttributes attributes = getAttributes(annotationMetadata); 16 // 调用方法获取所有可用配置:具体有那些可以看下一个方法 17 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); 18 // 这个步骤实现了筛选重复的配置信息 19 configurations = removeDuplicates(configurations); 20 // 获取所有需要排除的属性集(没有在项目中应用的) 21 Set<String> exclusions = getExclusions(annotationMetadata, attributes); 22 // 根据重复信息,和配出属性集,检查要排除的类 23 checkExcludedClasses(configurations, exclusions); 24 // 删除所有需要排除的属性集 25 configurations.removeAll(exclusions); 26 // 根据剩下的正确配置属性集,获取配置过滤器 27 configurations = getConfigurationClassFilter().filter(configurations); 28 // 启动自动装配的导入事件 29 fireAutoConfigurationImportEvents(configurations, exclusions); 30 // 返回所有自动配置项 31 return new AutoConfigurationEntry(configurations, exclusions); 32 } 33 34 // 省略其他方法等代码 35 /** 36 * 该方法将根据注解源数据和注解属性获取所有默认可用的配置信息 37 */ 38 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { 39 // 读取所有可用配置信息,从下面的一行代码中可以看出它所加载读取的文件 40 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), 41 getBeanClassLoader()); 42 // 判断集合中是否为空,若为空,则说明没有找到可用的自动配置信息(读取的文件时META-INF/spring.factories。) 43 Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " 44 + "are using a custom packaging, make sure that file is correct."); 45 // 最后返回读取的配置信息集合 46 return configurations; 47 }
Mavne找到Spring-Boot-autoconfigrue依赖,进入包META-INF打开文件:spring.factories
在上图中,配置源会判断是否启用自动装配,也只会加载已启用的配置,只要我们在pom文件中引入的组件,SpringBoot都会帮我们自动配置。
可以通过在核心配置文件中添加如下代码,实现控制台显示配置详情:
debug: true