@Target 作用: 指明了修饰的这个注解的使用范围, 即被描述的注解可以用在哪里@Target(ElementType.Type)ElementType取值的类型: TYPE: 类,接口或者枚举FIELD: 域,包含枚举常量METHOD: 方法PARAMETER: 参数CONSTRUCTOR: 构造方法LOCAL_VARIABLE: 局部变量ANNOTATION_TYPE: 注解类型PACKAGE: 包@Retention 作用: 指明修饰的注解的生存周期, 即会保留到哪个阶段RetentionPolicy 的取值类型有三种: SOURCE: 源码级别保留,编译后即丢弃CLASS: 编译级别保留,编译后的class 文件中存在,在jvm 运行时丢弃,这是默认值 RUNTIME: 运行级别保留,编译后的class 文件中存在,在jvm 运行时保留,可以被反射调用@Documented 作用: 指明修饰的注解,可以被例如javadoc 此类的工具文档化 @Inherited 作用: 允许子类继承 父类中的注解 @Inherited需要和@AliasFor一起使用: 在子注解对应的属性使用@AliasFor 注解是可以继承的,但是注解是不能继承父注解的属性 也就是说,在类扫描时的注解的属性值依然是父注解的属性值,而不是自定义注解的属性值 需要在注解的属性上使用@AliasFor @ComponentScan 作用: 定义扫描的路径从中找出标识了需要装配的类自动装配 到spring的bean容器中默认会扫描该类所在的包下所有的配置类 @ComponentScan中的参数类型: value: 用于对指定包的路径进行扫描basePackages: 用于指定包的路径进行扫描,用法和value一样.建议使用valuebasePackageClasses: 用于对指定某个类的所在的包的路径进行扫描nameGenerator: 用于为Spring容器中的检测到bean 组件命名useDefaultFilters: 是否开启对 @Component,@Repository,@Service,@Controller 的类进行检测excludeFilters: 按照过滤条件进行排除 FilterType.ANNOTATION: 按照注解FilterType.ASSIGNABLE_TYPE: 按照给定的类型FilterType.ASPECTJ: 使用ASPECTJ表达式FilterType.REGEX: 使用正则表达式FilterType.CUSTOM: 按照自定义规则includeFilters: 按照过滤条件进行包含 FilterType.ANNOTATION: 按照注解FilterType.ASSIGNABLE_TYPE: 按照给定的类型FilterType.ASPECTJ: 使用ASPECTJ表达式FilterType.REGEX: 使用正则表达式FilterType.CUSTOM: 按照自定义规则@Filter 作用: 配置过滤条件的过滤器注解@Filter中的参数类型: @interface 作用: 自定义注解自动继承java.lang.annotation.Annotation 接口,由编译程序自动完成其他细节 在定义注解时,不能继承其他的注解或接口 @interface用来声明一个注解: 其中的每一个方法实际上是声明一个配置参数 方法的名称就是参数的名称 方法的返回值类型就是参数的类型 返回值类型只能是基本类型,Class,String,enum 可以通过default 来声明参数的默认值 定义注解的格式: public @interface 注解名 {定义体}注解参数支持的数据类型: 基本数据类型: int,float,boolean,byte,double,char,long,shortString类型 Class类型 enum类型 Annotation类型 以上类型组合的数组 Annotation类型中参数设定规则: 只能用public或default默认访问权修饰: 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean 八种基本数据类型和String,Enum,Class,annotations 等数据类型,以及这一些类型的数组 如果只有一个参数成员,最好把参数名称设为value,后加小括号 注解元素的默认值: 注解元素必须有确定的值 要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null 因此使用空字符串或0作为默认值约束 这个约束使得处理器很难表现一个元素的存在或缺失 的状态: 因为每个注解的声明中,所有元素都存在,并且都具有相应的值 为了绕开这个约束,只能定义一些特殊的值(比如空字符串或者负数),表示某个元素不存在 @AliasFor 作用: 为注解的属性添加别名在同一个注解内,对两个不同的属性一起使用,互为别名: 无论为哪个属性名设置属性值,另一个属性名也是同样的属性值 互为别名的属性值必须相同,否则会报错 属性必须要有默认的属性值 public @interface RequestMapping {
@AliasFor("path") // 此时path和value值必须是一样的,否则会报错
String[] value() default {};
@AliasFor("value") // 此时path和value值必须是一样的,否则会报错
String[] path() default {};
}显式的覆盖元注解中的属性: 显式的为元注解的属性设置别名 属性类型,属性默认值必须相同 @AliasFor只能为作为当前注解的元注解起别名 示例: @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AopConfig.class)
public class AopUtilsTest {}要想替换 @ContextConfiguration(classes = AopConfig.class) 注解,可以这样定义一个标签:
@Retention(RetentionPolicy.RUNTIME)
@ContextConfiguration
public @interface Context {
@AliasFor(value = "classes", annotation = ContextConfiguration.class)
Class<?>[] cs() default {};
}因为 @ContextConfiguration 注解本身被定义为 @Inherited 的,所以Context注解即可理解为继承 @ContextConfiguration 注解 cs 属性等同于 @ContextConfiguration 属性中的classes 属性.使用了 @AliasFor 标签,分别设置: value: 作为哪个属性的别名annotation: 作为哪个注解的别名使用Context标签的可以达到同样效果:
@RunWith(SpringJUnit4ClassRunner.class)
@STC(cs = AopConfig.class)
public class AopUtilsTest {} @ContextConfiguration
public @interface MyTestConfig {
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] value() default {};
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] groovyScripts() default {};
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] xmlFiles() default {};
}这就是在统一注解中隐式声明别名:
在MyTestConfig 注解中 ,value,groovyScripts,xmlFiles 都定义为@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")的别名 在这个注解中 ,value,groovyScripts和xmlFiles 也互为别名 别名的传递: @AliasFor注解是允许别名之间的传递的: 如果A是B的别名,并且B是C的别名,那么A是C的别名 @MyTestConfig
public @interface GroovyOrXmlTestConfig {
@AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts")
String[] groovy() default {};
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] xml() default {};
}GroovyOrXmlTestConfig 把 @MyTestConfig 作为元注解定义了groovy 属性,并作为MyTestConfig 中的groovyScripts 属性的别名 定义了xml 属性,并作为ContextConfiguration 中的locations 属性的别名 因为MyTestConfig 中的groovyScripts 属性本身就是ContextConfiguration 中的locations 属性的别名,所以xml 属性和groovy 属性也互为别名 @Alias中的属性: annotation: 类类型,别名属性的类的类型,即别名的属性属于哪个注解类attribute: 需要别名的属性value: 属性的别名@Import @Import 支持导入普通的Java类,并声明为一个Bean@Import使用场景: @Import主要用在基于Java代码显式创建bean的过程中 @Import用于将多个分散的Java Config配置类融合成一个完整的config类 配置类的组合主要发生在跨模块或者跨包的配置类引用过程中: 将多个按功能或者按业务划分的配置文件导入到单个配置文件中,避免将所有配置写在一个配置中@Import与@ImportResource注解的作用类似 使用@ImportResource和@Value可以进行资源文件的读取 SpringBoot @SpringBootApplication 包含: @Configuration @EnableAutoConfiguration @ComponentScan 通常用在主类上 @ConfigurationProperties 可以使用 获取大量配置在和中参数的参数值
@ConfigurationProperties的使用:
前缀prefix 定义的相关的外部属性要绑定到类的字段上 根据SpringBoot宽松的绑定规则,类属性的名称必须与外部属性名称匹配 可以将类类型的bean使用@Bean注解的方法注入到另一个bean中,那么这个bean可以以类型安全的方式访问外部配置的参数值 可以简单地用一个值初始化一个字段来定义一个默认值. 最好与配置文件中的值相同 类本身可以是包私有的 类的字段必须有公共setter 方法 激活@ConfigurationProperties:
通过添加 @Component 注解让ComponentScan扫描到 只有当该类所在的包被Spring的@ComponentScan扫描到才会生效.默认情况下,该注解会扫描在主应用类下所有包结构 @Component
@ConfigurationProperties(prefix = "spring.logger")
class LogProperties {
...
}通过Spring 的Java Configuration 特性激活@ConfigurationProperties 只要MailModuleConfiguration 类被SpringBoot应用扫描到,就可以在应用上下文中访问MailModuleProperties bean @Configuration
class PropertiesConfig {
@Bean
public LogModuleProperties logModuleProperties() {
return new logModuleProperties();
}
}同时可以使用 注解使得SpringBoot找到这个类. 这个注解用了 实现
@Configuration
@EnableConfigurationProperties(LogModuleProperties.class)
class PropertiesConfig {
}激活一个 @ConfigurationProperties 类时最好模块化应用程序,并让每个模块提供自己的 @ConfigurationProperties 类,只提供模块需要的属性.这样可以使得在不影响其他模块的情况下重构一个模块中的属性变得更加方便.因此不建议在程序类本身上使用 @EnableConfigurationProperties, 应该在特定模块的 @Configuration 类上使用 @EnableConfigurationProperties, 该类也可以利用包私有的可见性对特定应用程序其余部分隐藏属性
@ConfigurationProerties中无法转换的属性: 当为 @ConfigurationProperties 中的属性配置错误的值时,又不希望SpringBoot应用启动失败.可以设置ignoreInvalidFields 注解属性为true, 默认为false @ConfigurationProperties(prefix = "spring.logger", ignoreInvalidFields = true)
public class LogModuleProperties {
private Boolean enabled = Boolean.True;
}SpringBoot将会设置enable 字段为设定好的默认值. 如果没有设定默认值 ,enabled 的值将为null, 因为这里定义的是boolean 的包装类Boolean
@ConfigurationProperties中未知的属性: 默认情况下,SpringBoot会忽略不能绑定到 @ConfigurationProperties 类字段的属性 当配置文件中又一个属性实际没有绑定到 @ConfigurationProperties 类时,希望SpringBoot启动失败 或者是以前使用过这个属性,但已经被删除了,希望被触发告知手动从application.properties 删除这个属性 这是需要设置ignoreUnknownFields 注解属性为false, 默认为true @ConfigurationProperties(prefix = "spring.logger", ignoreUnknownFields = false)
class LogModuleProperties {
private Boolean enabled = Boolean.TRUE;
private String defaultSubject;
} 对于ignoreUnkownFields, 在SpringBoot中可能有两个带有@ConfigurationProperties的类,同时绑定到了同一个命名空间 (namespace) 上,其中一个类可能知道某个属性,另一个类却不知道某个属性,这样会导致启动失败.所以这个属性不再使用
启动时校验@ConfigurationProperties: 如果希望配置参数在传入到应用中是有效的,可以通过在字段上添加bean validation 注解,同时在类上添加 @Validated 注解 @ConfigurationProperties(prefix = "spring.logger")
@Validated
@Data
class LogModuleProperties {
@NotNull private Boolean enabled;
@NotEmty private String defaultSubject;
} 如果这些默认的验证注解不能满足验证要求的,可以自定义注解. 如果验证逻辑很特殊,可以实现一个方法,并用 @PostConstruct 标记,如果验证失败,方法抛出异常即可
复杂属性类型:
多数情况下,传递给应用的参数是基本字符串或者数字,有时又需要传递比如List的数据类型
List和Set:
有两种方式让SpringBoot自动填充属性:
set
推荐使用YML做数据配置,能够更好的阅读,层次分明
Duration:
SpringBoot内置支持从配置参数中解析duration (持续时间): @Data
@ConfigurationProperties(prefix = "spring.logger")
class loggerModuleProperties {
private Duration pauseBetweenLogs;
}spring.logger.pause-between-logs=5s如果配置duration 没有写单位,默认按照毫秒来指定,也可以通过 @DurationUnit 来指定单位: @Data
@ConfigurationProperties(prefix = "spring.logger")
class loggerModuleProperties {
@DurationUnit(ChronoUnit.SECONDS)
private Duration pauseBetweenLogs;
}常用单位如下: ns: NANOSECONDS - 纳秒us: MICROSECONDS - 微秒ms: MILLISECONDS - 毫秒s: SECONDS - 秒m: MINUTES - 分h: HOURS - 时d: DAYS - 天 DataSize:
与Duration用法一样,默认单位是byte (字节) , 可以通过@DataSizeUnit单位指定 @Data
@ConfigurationProperties(prefix = "spring.logger")
class loggerMailModuleProperties {
@DataSizeUnit(DataUnit.MEGABYTES)
private DataSize maxAttachmentSize = DataSize.ofMegebytes(2);
} spring.logger.max-attachment-size=1MB
B(bytes)
常见单位如下: B: BYTESKB: KILOBYTESMB: MEGEBYTESGB: GIGABYTESTB: TERABYTES 自定义类型:
有时候,想解析配置参数到自定义的对象类型上,比如自定义物品重量: spring.logger.max-attachment-weight=5kg在MailModuleProeprties 中添加Weight 属性: @Data
@ConfigurationProperties(prefix = "spring.logger")
class MailModuleProperties {
private Weight maxAttachmentWeight;
}class WeightConverter implements Convert<String, Object> {
@Override
public Weight convert(String source) {
// 根据String类型的source创建并返回一个Weight类型的对象
}
}将自定义转换器converter 注册到SpringBoot 上下文中 @Configuration
class PropertiesConfig {
@Bean
@ConfigurationPropertiesBinding
public WeightConverter weightConverter() {
return new WeightConverter();
}
}
@ConfigurationPropertiesBindingSpringBoot
标记配置属性为Deprecated:
@DeprecatedConfigurationProperty(reason = "change name", replacement = "none")
public String getDefaultSubject() {
return defaultSubject;
}可以通过添加 @DeprecatedConfigurationProperty注解 到字段的getter 方法上,来标示该字段为deprecated
SpringBoot 的 @ConfigurationProperties 注解在绑定类型安全的Java Bean 时是非常强大的可以配合其注解属性和 @DeprecatedConfigurationProperty 注解让配置更加模块化 如果使用SpEL 表达式,只能选择 @Value 注解 @Repository @Service @RestController @Controller 用于标注控制层组件 需要返回页面时要使用 @Controller 而不是 @RestController @ControllerAdvice 用于定义 @ExceptionHandler, @InitBinder, @ModelAttribute, 并且应用到所有 @RequestMapping 中 @InitBinder: 在执行之前初始化数据绑定器@ModelAttribute: 把值绑定到Model中,可以获取到该值@ExceptionHandler: 全局异常捕捉处理 @Component 泛指组件 当组件无法归类时,可以使用这个注解进行标注 @ResponseBody 表示该方法的返回结果直接被写入http response body 中 在使用 @RequestMapping 后,返回值通常解析为跳转路径 比如: 加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入HTTP Response Body 中 异步获取json数据,加上 @ResponseBody 后,会直接返回json 数据 @RequestBody 参数前加上这个注解,表示该参数必填 表示接收json字符串转为对象List @ComponentScan 组件扫描 扫描到有 @Component, @Cotroller, @Service 等这些注解的类,就会把这些类注册为bean * @Configuration 表示该类是Bean 的信息源 相当于XML中的,一般标注在主类上 @ConditionOnProperty 控制Configuration 在条件成立时生效 属性: value: 数组,获取对应property 的名称,与name 不可以同时使用prefix: property 名称的前缀,可有可无name: 数组 ,property 完整名称或者部分名称(与prefix 组合使用,组成完整的property 名称),不可以与value 同时使用havingValue: 可与name 组合使用,比较获取到的属性值与havingValue 给定的值是否相同,相同才加载配置matchMissing: 缺少该property 时是否可以加载. 如果为true, 没有该property 也会正常加载. 如果为false, 则没有该property 时则会报错,默认为false relaxedNames: 是否支持松散匹配@Bean 相当于XML中的,标注在方法上 表示生成一个bean, 并交给Spring 管理 @EnableAutoConfiguration 使SpringBoot 根据应用所声明的依赖来对Spring框架进行配置 一般加在主类上 @Autowired byType 方式使用已经配置好的Bean, 完成属性,方法的组装 可以对类成员,方法以及构造函数进行标注,完成自动装配的工作 如果加上 @Autowired(required = false), 当找不到bean 时也不会报错 @Qualifier 当有多个同一类型的Bean 时,可以使用 @Qualifier("name") 来指定 需要和 @Autowired 一起使用 @Resource @Resource(name = "name", type = "type") 如果没有属性的话,默认为byName, 与 @Autowired 功能类似 @RequestMapping @RequestMapping 是一个用来处理请求地址映射的注解,可以使用在类或者方法上用在类上时,表示类中所有响应请求的方法都以该地址作为父路径 @RequestMapping有六个属性: params: 指定request中必须包含某些参数值,才让该方法处理请求headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求value: 指定请求的实际地址. 指定的地址可以是URI Template 模式method: 指定请求的method 类型 ,GET, POST, PUT,DELETE 等consumes: 指定处理请求的提交内容类型 - Content-Type. 比如: application,json,text,html produces: 指定返回的内容类型,仅当request请求头中的 (Accept) 类型中包含该指定类型才返回@GetMapping @GetMapping, @PostMapping 是组合注解相当于 @RequestMapping(value = "/", method = RequestMethod.Get(Post, Put, Delete)) @RequestParam 用在方法的参数前面 相当于 request.getParameter @PathVariable 路径变量: RequestMapping("user/get/mac/{macAddress}") public String getByMacAddress(@PathVariable("macAddress") String macAddress) {}参数与大括号里的名字相同的话,注解后括号里的内容可以不填
全局异常处理 @ControllerAdvice 包含 @Component 可以被扫描到 统一异常处理 @ExceptionHandler @Exceptionhandler(Exception.class) SpringCloud @EnableEurekaServer 用在SpringBoot 启动类上 表示这是一个Eureka 服务注册中心 @EnableDiscoveryClient 用在SpringBoot启动类上 表示这是一个服务,可以被注册中心找到 @LoadBalanced @EnableCircuitBreaker HystrixCommand @HystrixCommand(fallbackMethod = "backMethod") 用在方法上,表示fallbackMethod指定断路回调方法 @EnableConfigServer 用在SpringBoot 启动类上 表示这是一个配置中心,开启Config Server @EnableZuulProxy 用在SpringBoot启动类上 表示开启zuul 路由 @SpringCloudApplication 微服务注解集合,包含: @SpringBootApplication: SpringBoot注解@EnableDiscoveryClient: 注册服务中心Eureka注解@EnableCircuitBreaker: 断路器注解这是每一个微服务必须应该有的注解