您的浏览器过于古老 & 陈旧。为了更好的访问体验, 请 升级你的浏览器
一纸荒年 发布于2019年12月02日 11:46

原创 Spring注解的详解

27 次浏览 读完需要≈ 34 分钟 Spring

内容目录

查找所有注解

首先,我们来创建一个项目,使用Spring Initializer生成一个引入Spring各种组件的项目模板,然后引入如下工具包:

<dependency>
    <groupId>org.reflections</groupId>
    <artifactId>reflections</artifactId>
    <version>0.9.11</version>
</dependency>

通过这个反射工具包,我们可以创建一个Spring Boot应用程序,以一行代码打印出所有Spring框架的注解:

import org.reflections.Reflections;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;

@Component
public class ScanAnnotationRunner implements CommandLineRunner {    
	 @Override 
	 public void run(String... args) throws Exception {        
	    new Reflections("org.springframework")
	         .getSubTypesOf(Annotation.class)
	         .stream()
	         .map(clazz->clazz.getName())
	         .sorted()
	         .forEach(System.out::println);
	    }
}

有关注解

Java的Annotation注解:

我们可以配置这个标签的保留阶段,仅源代码,源代码+字节码,源代码+字节码+运行时。通过引入注解,我们可以简单快速赋予代码生命力,大大提高代码可读性和扩展性。注解本身不具有任何能力,只是一个标签,但是我们可以定义各种标签然后实现各种标签处理器来对类、方法、属性甚至参数等进行功能扩展、功能开启、属性定义、行为定义、规则定义、关联处理、元数据定义等等。在实现各种框架的时候,我们经常会自定义标签方便框架使用者仅仅通过在合适的地方引入合适的注解来启用(或自定义)框架的一些能力并应用到我们的程序中。

Java Annotation 的组成中,有 3 个非常重要的主干类。它们分别是:

package java.lang.annotation;
public interface Annotation {

    boolean equals(Object obj);

    int hashCode();

    String toString();

    Class<? extends Annotation> annotationType();
}
package java.lang.annotation;

public enum ElementType {
    TYPE,               /* 类、接口(包括注释类型)或枚举声明  */

    FIELD,              /* 字段声明(包括枚举常量)  */

    METHOD,             /* 方法声明  */

    PARAMETER,          /* 参数声明  */

    CONSTRUCTOR,        /* 构造方法声明  */

    LOCAL_VARIABLE,     /* 局部变量声明  */

    ANNOTATION_TYPE,    /* 注释类型声明  */

    PACKAGE             /* 包声明  */
}
package java.lang.annotation;
public enum RetentionPolicy {
    SOURCE,            /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了  */

    CLASS,             /* 编译器将Annotation存储于类对应的.class文件中。默认行为  */

    RUNTIME            /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}

有关如何实现自定义注解不赘述,这里我们简单回顾一下几个元注解(注解的注解):

名称 描述
@Documented 将会在被此注解注解的元素的javadoc文档中列出注解,一般都打上这个注解没坏处
@Target 注解能被应用的目标元素,比如类、方法、属性、参数等等,需要仔细思考
@Retention 仅在源码保留,还是保留到编译后的字节码,还是到运行时也去加载,超过90%的应用会在运行时去解析注解进行额外的处理,所以大部分情况我们都会设置配置为RetentionPolicy.RUNTIME
@Inherited 如果子类没有定义注解的话,能自动从父类获取定义了继承属性的注解,比如Spring的@Service是没有继承特性的,但是@Transactional是有继承特性的,在OO继承体系中使用Spring注解的时候请特别注意这点,理所当然认为注解是能被子类继承的话可能会引起不必要的Bug,需要仔细斟酌是否开启继承
@Repeatable Java 8 引入的特性,通过关联注解容器定义可重复注解,小小语法糖提高了代码可读性,对于元素有多个重复注解其实是很常见的事情,比如某方法可以是A角色可以访问也可以是B角色可以访问,某方法需要定时任务执行,要在A条件执行也需要在B条件执行
@Native 是否在.h头文件中生成被标记的字段,除非原生程序需要和Java程序交互,否则很少会用到这个元注解

Spring核心注解

类型 名称 描述
Spring管理的各种组件 @Controller 定义表现层组件
@Service 定义业务逻辑层组件
@Repository 定义数据访问层资源库组件
@Component 定义其它组件(比如访问外部服务的组件)
IOC相关的一些注解 @Autowired 自动装配
@Required 用于在setter方法标记属性值需要由Spring进行装配
@Qualifier 用于通过给Bean定义修饰语来注入相应的Bean
@Value 用于注入属性配置或SpEL表达式
@Lookup

可以实现方法注入,如果我们的类是单例的,但是又希望Spring注入的依赖的对象

是Prototype生命周期(每次new一个出来)的,这个时候可以通过此注解进行方法注入

有关事务的几个注解 @EnableTransactionManagement 用于开启事务管理,使用Spring Boot如果引入Spring Data的话不需要手动开启
@Transactional 用于开启事务以及设置传播性、隔离性、回滚条件等
@TransactionalEventListener 用于配置事务的回调方法
Spring管理对象的加载顺序 @Order 可以设置Spring管理对象的加载顺序
Spring管理对象的设置别名 @AliasFor 可以设置一组注解属性相互作为别名

Spring上下文注解

名称 描述
@Configuration 用于标注配置类,启用Java配置方式的Bean配置
@Bean 用于配置一个Bean
ComponentScan 用于扫描包方式配置Bean
@PropertySource 用于导入配置文件
@Conditional 用于设置关联的条件类
@Import 用于导入其它配置类
@ImportResource 用于导入非Java配置方式的XML配置
@Profile 用于指定在合适的Profile下启用配置
@Lazy 用于告知容器延迟到使用的时候实例化Bean
@Description 用于给Bean设置描述
@Scope 用于设置Bean的生命周期
@Primary 用于在定义了多个Bean的时候指定首选的Bean
@EventListener 用于设置回调方法监听Spring制定的以及自定义的各种事件
@EnableAspectJAutoProxy 用于开启支持AspectJ的
@Aspect 用于切面配置支持

Spring Web注解

名称 描述
@RequestScope 定义了Bean请求生命周期的复合注解
@SessionScope 定义了Bean会话生命周期的复合注解
@ApplicationScope 定义了Bean应用程序生命周期的复合注解
@XXXMapping 用于配置HandlerMethod匹配到不同的Http Method
@RequestMapping 手动设置Http Method
@ResponseStatus

方法上:会直接使请求得到指定的响应代码或原因

异常上:实现遇到指定异常的时候给出指定的响应代码或原因

@ResponseBody 返回内容(序列化后)输出到请求体
@RequestBody 从请求体处理复杂数据,比如JSON
@RequestHeader 从请求头处理数据
@CookieValue 从cookie处理数据
@SessionAttribute 从会话处理数据
@RequestAttribute 从请求的Attribute中处理数据
@RequestParam 从请求参数中处理数据
@PathVariable 处理数据
@ModelAttrbuute 绑定键值对到Model中
@MatrixAttribute 矩阵变量允许我们采用特殊的规则在URL路径后加参数
@ControllerAdvice 允许在集中的地方配置控制器
@ExceptionHandler 设置异常处理
@InitBinder 用来设置WebDataBinder
@CrossOrigin 设置细粒度的跨域行为

Spring Boot注解

名称 描述
@ConfigurationProperties 用来自定义配置类和配置文件进行关联
@DeprecatedConfigurationProperty 用于标记废弃的配置以及设置替代配置和告知废弃原因
@ConfigurationPropertiesBinding 用于指定自定义的转换器用于配置解析的时的类型转换
@NestedConfigurationProperty 用于关联外部的类型作为嵌套配置类
@EnableAutoConfiguration 用于启用自动配置
@AutoConfigureOrder 用于设置优先级,值越小优先级越高
@AutoConfigureAfter 用于设置自动配置类加载顺序
@AutoConfigureBefore 用于设置自动配置类加载顺序
@ConditionalOnBean 用于仅当容器中已经包含指定的Bean类型或名称时才匹配条件
@ConditionalOnClass 仅当classpath上存在指定类时条件匹配
@ConditionalOnCloudPlatform 仅当指定的云平台处于活动状态时条件匹配
@ConditionalOnExpression 依赖于SpEL表达式的值的条件元素的配置注解
@ConditionalOnJava 基于应用运行的JVM版本的条件匹配
@ConditionalOnJndi 基于JNDI可用和可以查找指定位置的条件匹配
@ConditionalOnMissingBean 仅当容器中不包含指定的Bean类型或名称时条件匹配
@ConditionalOnMissingClass 仅当classpath上不存在指定类时条件匹配
@ConditionalOnNotWebApplication 仅当不是WebApplicationContext(非Web项目)时条件匹配
@ConditionalOnProperty 检查指定的属性是否具有指定的值
@ConditionalOnResource 表示仅当 classpath 上存在指定资源时条件匹配
@ConditionalOnSingleCandidate 当容器中包含指定的Bean类并且可以判断只有单个候选者时条件匹配

Spring Cloud注解

名称 描述
@RibbonClient 用来为负载均衡客户端做一些自定义的配置
@Scope 用于指定scope作用域
@Lazy(true) 表示延迟初始化
@Service 用于标注业务层组件
@Controller 用于标注控制层组件
@Repository 用于标注数据访问组件
@Component 当组件不好归类的时候,我们可以使用这个注解进行标注
@PostConstruct 用于指定初始化方法
@PreDestory 用于指定销毁方法
@Resource 默认按名称装配
@DependsOn 定义Bean初始化及销毁时的顺序
@Primary 自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配
@Async 异步方法调用
@Configuration 表示将该类作用springboot配置文件类
@LoadBalanced 方便我们对RestTemplate添加一个LoadBalancerClient,以实现客户端负载均衡
  • CodePlayer技术交流群1
  • CodePlayer技术交流群2

0 条评论

撰写评论