详细解析Java中各个注解的作用和使用方式

2021-06-28  本文已影响0人  攻城狮Chova

@Target

@Target(ElementType.Type)

@Retention

@Documented

@Inherited

@ComponentScan

@Filter

@interface

public @interface 注解名 {定义体}

@AliasFor

public @interface RequestMapping {
   
    @AliasFor("path")           // 此时path和value值必须是一样的,否则会报错
    String[] value() default {};

    @AliasFor("value")          // 此时path和value值必须是一样的,否则会报错
    String[] path() default {};
    
}
@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也互为别名
@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属性也互为别名

@Import

SpringBoot

@SpringBootApplication

@ConfigurationProperties

@Configuration
@EnableConfigurationProperties(LogModuleProperties.class)
class PropertiesConfig {
}

激活一个 @ConfigurationProperties类时最好模块化应用程序,并让每个模块提供自己的 @ConfigurationProperties类,只提供模块需要的属性.这样可以使得在不影响其他模块的情况下重构一个模块中的属性变得更加方便.因此不建议在程序类本身上使用 @EnableConfigurationProperties, 应该在特定模块的 @Configuration类上使用 @EnableConfigurationProperties, 该类也可以利用包私有的可见性对特定应用程序其余部分隐藏属性

@ConfigurationProperties(prefix = "spring.logger", ignoreInvalidFields = true)
public class LogModuleProperties {
    private Boolean enabled = Boolean.True;
}

SpringBoot将会设置enable字段为设定好的默认值. 如果没有设定默认值 ,enabled的值将为null, 因为这里定义的是boolean的包装类Boolean

@ConfigurationProperties(prefix = "spring.logger", ignoreUnknownFields = false)
class LogModuleProperties {
    private Boolean enabled = Boolean.TRUE;
    private String defaultSubject;
}

对于ignoreUnkownFields, 在SpringBoot中可能有两个带有@ConfigurationProperties的类,同时绑定到了同一个命名空间 (namespace) 上,其中一个类可能知道某个属性,另一个类却不知道某个属性,这样会导致启动失败.所以这个属性不再使用

@ConfigurationProperties(prefix = "spring.logger")
@Validated
@Data
class LogModuleProperties {
    @NotNull private Boolean enabled;
    @NotEmty private String defaultSubject;
} 

如果这些默认的验证注解不能满足验证要求的,可以自定义注解. 如果验证逻辑很特殊,可以实现一个方法,并用 @PostConstruct标记,如果验证失败,方法抛出异常即可

@DeprecatedConfigurationProperty(reason = "change name", replacement = "none")
public String getDefaultSubject() {
    return defaultSubject;
}

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

@Repository

@Service

@RestController

@Controller

@ControllerAdvice

@Component

@ResponseBody

@RequestBody

@ComponentScan

@Configuration

@ConditionOnProperty

@Bean

@EnableAutoConfiguration

@Autowired

@Qualifier

@Resource

@RequestMapping

@GetMapping

@RequestParam

@PathVariable

public String getByMacAddress(@PathVariable("macAddress") String macAddress) {}

参数与大括号里的名字相同的话,注解后括号里的内容可以不填

全局异常处理

@ControllerAdvice

@ExceptionHandler

SpringCloud

@EnableEurekaServer

@EnableDiscoveryClient

@LoadBalanced

@EnableCircuitBreaker

HystrixCommand

@EnableConfigServer

@EnableZuulProxy

@SpringCloudApplication

上一篇 下一篇

猜你喜欢

热点阅读