SpringBoot进阶-自动配置原理、元注解、异常处理及单元测试
概述
本文讲解Spring Boot 的自动配置原理、元注解、异常的处理,以及单元测试。
自动配置
注解@SpringBootApplication
入口类默认提供了注解 @SpringBootApplication ,它用于标注 Spring Boot 项目的入口。这一个注解被 @Configuration 、@EnableAutoConfiguration 、@ComponentScan 这三个注解所修饰,即 Spring Boot 提供了统一的注解 @SpringBootApplication 来替代这三个注解。
自动配置的原理
在入口类中,默认使用了注解 @EnableAutoConfiguration ,Spring Boot 也正是通过它来完成自动配置的。
注解 @EnableAutoConfiguration 借助注解 @Import ,将所有符合自动配置条件的 Bean 都加载到 IoC 容器中,其关键代码如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
从上述代码可以看到,通过注解 @Import 导入了 “AutoConfigurationImportSelector.class” ,Spring Boot 借助它将所有符合条件的 @Configuration 配置都加载到 IoC 容器中。
AutoConfigurationImportSelector 类会调用 “SpringFactoriesLoader” 类,进入 SpringFactoriesLoader 类中,其关键代码如下:
public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
从上述代码可以看到, SpringFactoriesLoader 从 classpath 中寻找所有的 META-INF/spring.factories 配置文件。
由上可以看出,Spring Boot 自动配置原理(EnableAutoConfiguration类)的工作原理:
- 它借助 AutoConfigurationImportSelector ,调用 SpringFactoriesLoader 的 loadFactoryNames 方法,从 classpath 中寻找所有的 META-INF/spring.factories 配置文件(spring.factories 配置了自动装配的类);
- 然后,再借助 AutoConfigurationImportSelector ,将所有符合条件的
@Configuration 配置都加载到 IoC 容器中。
元注解
元注解就是定义注解的注解,是 Java 提供的用于定义注解的基本注解。
元注解:
@Retention 是注解类,实现声明类 Class ,声明类别 Category ,声明扩展 Extension@Target 放在自定义注解的上边,表明该注解可以使用的范围@Inherited 允许子类继承父类的注解,在子类中可以获取使用父类注解@Documented 表明这个注解是由 Javadoc 记录的@interface 用来自定义注解类型
@Target 标注作用范围
@Target 该注解的作用是告诉 Java 将自定义的注解放在什么地方,比如类、方法、构造器、变量上等。它是一个枚举类型,有如下值:
@Target(ElementType.CONSTRUCTOR) 用于描述构造器@Target(ElementType.FIELD) 用于描述成员变量、对象、属性、枚举的常量@Target(ElementType.LOCAL_VARIABLE) 用于描述局部变量@Target(ElementType.METHOD) 用于描述方法@Target(ElementType.PACKAGE) 用于描述包@Target(ElementType.PARAMETER) 用于描述方法参数@Target(ElementType.TYPE) 用于描述接口、类、枚举、注解@Target(ElementType.ANNOTATION_TYPE) 用于描述注解
使用多个作用范围 @Target({ElementType.METHOD,ElementType.TYPE}) 。
@Retention 标注生命周期
该注解用于说明自定义注解的生命周期,在注解中有三个生命周期:
@Retention(RetentionPolicy.RUNTIME) 始终不会丢弃,运行期也保留该注解,可以使用反射机制读取该注解的信息。自定义的注解通常使用这种方式。@Retention(RetentionPolicy.CLASS) 类加载时丢弃,默认使用这种方式。@Retention(RetentionPolicy.SOURCE) 编译阶段丢弃,注解在编译结束之后就不再有意义。所以它们不会写入字节码。 @Override 、 @SuppressWarnnings 都属于这类注解。
@Inherited
该注解是一个标记注解,表明被标注的类型是可以被继承的。如果一个使用了 @Inherited 修饰的 Annotation 类型被用于一个 Class ,则这个 Annotation 将被用于该 Class 的子类。
subClazz.getAnnotations()) 可以获取到自身和其父类的注解。
subClazz.getDeclaredAnnotations() 只获取自身的注解。
@Documented
表示将注解信息添加到 Java 文档中。
@interface
该注解用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。
方法名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。
可以通过 default 来声明参数的默认值。
异常处理
异常处理是编程语言的机制,用来处理软件系统中出现的异常状况。
异常处理的必要性
异常处理用于解决一些程序无法掌控,但又必须面对的情况。例如,程序需要读取文件、连接网络、使用数据库等,但可能文件不存在、网络不畅通、数据库无效等情况。为了程序能继续运行,此时就需要把这些情况进行异常处理。
异常处理的方法通常有以下几种:
- 将异常通知给开发人员、运维人员或用户。
- 使因为异常中断的程序以适当的方式继续运行,或者退出。
- 保存用户的当前操作,或者进行数据回滚。
- 释放资源。
异常的分类
- Error :代表编译和系统的错误,不允许捕获。
- Exception :标准 Java 库的方法所激发的异常,包含运行时异常 RuntimeException 和非运行时异常 Non_RuntimeException 的子类。
- RuntimeException :运行时异常。
- Non_RuntimeException :非运行时可检测的异常, Java 编译器利用分析方法或构造方法中可能产生的结果来检测程序中是否含有检测异常的处理程序,每个可能的可检测异常、方法或构造方法的 throws 子名必须列出该异常对应的类。
单元测试
单元测试(unit test)是为了检验程序的正确性。一个单元可能是单个程序、类、对象、方法等,它是应用程序的最小可测试部件。
单元测试的必要性:
- 预防bug
- 快速定位 bug
- 提高代码质量,减少耦合
- 减少调试时间
- 减少重构的风险
Spring Boot 的测试库
Spring Boot 提供了 spring-boot-starter-test 启动器。通过它,能引入一些有用的测试库,如下所示:
- Spring Test & Spring Boot Test :Spring Boot 提供的应用程序功能集成化测试支持。
- JUnit : Java 应用程序单元测试标准类库。
- AssertJ :轻量级的断言类库。
- Hamcrest : 对象匹配器类库。
- Mockito : Java Mock 测试框架。
- JsonPath : JSON 操作类库。
- JSONassert : 用于JSON的断言库。
了解回归测试框架 JUnit
JUnit 是对程序代码进行单元测试的 Java 框架。它用来编写自动化测试工具,降低测试的难度、减少烦琐性,并有效避免出现程序错误。
JUnit 测试是白盒测试。
总结
自动配置
Spring Boot 自动配置原理(EnableAutoConfiguration类)的工作原理:
- 它借助 AutoConfigurationImportSelector ,调用 SpringFactoriesLoader 的 loadFactoryNames 方法,从 classpath 中寻找所有的 META-INF/spring.factories 配置文件(spring.factories 配置了自动装配的类);
- 然后,再借助 AutoConfigurationImportSelector ,将所有符合条件的
@Configuration 配置都加载到 IoC 容器中。
元注解
元注解就是定义注解的注解,是 Java 提供的用于定义注解的。
@Target 标注作用范围@Retention 标注生命周期@Inherited 标注注解会被被标注类的子类继承@Documented 标注注解会被添加到 Java doc 文档中@interface 用来声明注解,可以用来创建自定义注解
异常处理
异常处理是编程语言的机制,用来处理软件系统中出现的异常状况。
异常的分类
- Error :代表编译和系统的错误,不允许捕获。
- Exception :标准 Java 库的方法所激发的异常,包含运行时异常 RuntimeException 和非运行时异常 Non_RuntimeException 的子类。
单元测试
单元测试(unit test)是为了检验程序的正确性。 Spring Boot 提供了 spring-boot-starter-test 启动器。通过它,能引入一些有用的测试库
公众号
参考
《Spring Boot 实战派》 龙中华
|