注解式项目开发!解析Java中各个注解的作用和使用方式

  • 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一样.建议使用value
    • basePackageClasses: 用于对指定某个类的所在的包的路径进行扫描
    • 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中的参数类型:
    • type
    • class

@interface

  • 作用: 自定义注解
  • 自动继承 java.lang.annotation.Annotation 接口,由编译程序自动完成其他细节
  • 在定义注解时,不能继承其他的注解或接口
  • @interface用来声明一个注解:
    • 其中的每一个方法实际上是声明一个配置参数
    • 方法的名称就是参数的名称
    • 方法的返回值类型就是参数的类型
    • 返回值类型只能是基本类型,Class,String,enum
    • 可以通过 default 来声明参数的默认值
  • 定义注解的格式:
public @interface 注解名 {定义体}
  • 注解参数支持的数据类型:
    • 基本数据类型: int,float,boolean,byte,double,char,long,short
    • String类型
    • 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 {};
}
  1. 因为 @ContextConfiguration 注解本身被定义为 @Inherited 的,所以Context注解即可理解为继承 @ContextConfiguration 注解
  2. cs 属性等同于 @ContextConfiguration 属性中的 classes 属性.使用了 @AliasFor 标签,分别设置:
    1. value: 作为哪个属性的别名
    2. 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 {};
 }

这就是在统一注解中隐式声明别名:

  1. 在 MyTestConfig 注解中 ,value,groovyScripts,xmlFiles 都定义为@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")的别名
  2. 在这个注解中 ,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 {};
 }
  1. GroovyOrXmlTestConfig 把 @MyTestConfig 作为元注解
  2. 定义了 groovy 属性,并作为 MyTestConfig 中的 groovyScripts 属性的别名
  3. 定义了 xml 属性,并作为 ContextConfiguration 中的 locations 属性的别名
  4. 因为 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 获取大量配置在 application.properties 和 application.yml 中参数的参数值
  • @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();
    	}
    }
  • 同时可以使用 @EnableConfigurationProperties 注解使得SpringBoot找到这个类. 这个注解用了 @Import(EnableConfigurationPropertiesImportSelector.class) 实现
@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自动填充 List 属性:
        • 在 application.properties 文件中以 数组 形式书写
        spring.logger.smtpServers[0]=server1
        spring.logger.smtpServers[1]=server1
        • application.yml 本身支持 List 类型,可以在application.yml文件中添加
        spring:
        	mail:
        		smtpServers:
        			- server1
        			- server2
      • 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: BYTES
      • KB: KILOBYTES
      • MB: MEGEBYTES
      • GB: GIGABYTES
      • TB: TERABYTES
  • 自定义类型:
    • 有时候,想解析配置参数到自定义的对象类型上,比如自定义物品重量:
    spring.logger.max-attachment-weight=5kg
    • 在 MailModuleProeprties 中添加 Weight 属性:
    @Data
    @ConfigurationProperties(prefix = "spring.logger")
    class MailModuleProperties {
    	private Weight maxAttachmentWeight;
    }
    • 创建自定义转换器 converter:
    class WeightConverter implements Convert {
    	@Override
    	public Weight convert(String source) {
    		// 根据String类型的source创建并返回一个Weight类型的对象
    	}
    }
    • 将自定义转换器 converter 注册到 SpringBoot 上下文中
    @Configuration
    class PropertiesConfig {
    	@Bean
    	@ConfigurationPropertiesBinding
    	public WeightConverter weightConverter() {
    		return new WeightConverter();
    	}
    }
    @ConfigurationPropertiesBinding 注解是让 SpringBoot 使用该转换器做数据绑定
  • 标记配置属性为Deprecated:
@DeprecatedConfigurationProperty(reason = "change name", replacement = "none")
public String getDefaultSubject() {
	return defaultSubject;
}

可以通过添加 @DeprecatedConfigurationProperty注解 到字段的 getter 方法上,来标示该字段为 deprecated

  • SpringBoot 的 @ConfigurationProperties 注解在绑定类型安全的 Java Bean 时是非常强大的
  • 可以配合其注解属性和 @DeprecatedConfigurationProperty 注解让配置更加模块化
  • 如果使用 SpEL 表达式,只能选择 @Value 注解

@Repository

  • 用于标注数据访问组件,即DAO组件

@Service

  • 用于标注业务层组件

@RestController

  • 用于标注控制层组件
  • 包含:
    • @Controller
    • @ResponseBody

@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

  • 用在SpringBoot启动类上
  • 开启断路器功能

HystrixCommand

  • @HystrixCommand(fallbackMethod = "backMethod")
  • 用在方法上,表示fallbackMethod指定断路回调方法

@EnableConfigServer

  • 用在 SpringBoot 启动类上
  • 表示这是一个配置中心,开启 Config Server

@EnableZuulProxy

  • 用在SpringBoot启动类上
  • 表示开启 zuul 路由

@SpringCloudApplication

  • 微服务注解集合,包含:
    • @SpringBootApplication: SpringBoot注解
    • @EnableDiscoveryClient: 注册服务中心Eureka注解
    • @EnableCircuitBreaker: 断路器注解
  • 这是每一个微服务必须应该有的注解

需要资料的小伙伴,点赞加收藏,关注我之后添加小助理vx:bjmsb0606006 即可获取免费下载方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值