关于注解:注解式项目开发详细解析Java中各个注解的作用和使用方式

4次阅读

共计 11874 个字符,预计需要花费 30 分钟才能阅读完成。

@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 一样. 倡议应用 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 {};}
  • 因为 @ContextConfiguration注解自身被定义为 @Inherited的, 所以 Context 注解即可了解为继承 @ContextConfiguration注解
  • 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 {};}

    这就是在对立注解中隐式申明别名:

  • 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获取大量配置在 application.propertiesapplication.yml中参数的参数值
  • @ConfigurationProperties 的应用: 要为每个捕捉的内部属性提供一个带有字段的类

    • 前缀 prefix 定义的相干的内部属性要绑定到类的字段上
    • 依据 SpringBoot 宽松的绑定规定, 类属性的名称必须与内部属性名称匹配

      • 能够将类类型的 bean 应用 @Bean 注解的办法注入到另一个 bean 中, 那么这个 bean 能够以类型平安的形式拜访内部配置的参数值
    • 能够简略地用一个值初始化一个字段来定义一个默认值. 最好与配置文件中的值雷同
    • 类自身能够是包公有的
    • 类的字段必须有公共 setter 办法
  • 激活 @ConfigurationProperties:

    • 通过增加 @Component注解让 ComponentScan 扫描到
    • 只有当该类所在的包被 Spring 的 @ComponentScan 扫描到才会失效. 默认状况下, 该注解会扫描在主利用类下所有包构造

      @Component
      @ConfigurationProperties(prefix = "spring.logger")
      class LogProperties {...}
    • 通过 SpringJava 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<String, Object> {
        @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: 断路器注解
  • 这是每一个微服务必须应该有的注解
正文完
 0