1. 概要

  • 格式

public @interface 注解名称{
属性列表;
}

  • 使用位置:详见 @Target;
  • 级别:和 类、接口、枚举 属于同一级别;
  • 实质:能被程序所理解,且为当前读取该注释的程序提供判断依据的注释或标签;
  • 应用:Annotation 是一个辅助类,在 Junit、Struts、Spring 等工具框架中被广泛使用;
  • 注解的“铁三角”关系:定义注解、使用注解、读取注解,欠缺任何一环,都无法发挥注解的真正作用;
  • 分类:大致可分为 自定义注解、JDK内置注解、还有第三方框架提供的注解 三类;

    2. JDK 内置注解

    2.1 标准注解

  • @Override - 只能标注方法,表示该方法覆盖父类中的方法,检查该方法是否是重载方法,如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误;

  • @Deprecated - 标记过时方法,所标注内容不再被建议使用,如果使用该方法,会报编译警告;
  • @SuppressWarnings - 指示编译器去忽略注解中声明的警告;
  • @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告;
  • @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口;
  • @Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次;

    2.2 元注解

  • 作用在注解上的注解,所在包 java.lang.annotation;

  • @Retention :用于描述注解的生命周期(即:被描述的注解在什么范围内有效),并由编译器存储到指定位置,可有可无,默认 class;
    • RetentionPolicy:Enum 枚举类型,用于指定 Annotation 的作用生命域;
      • SOURCE:仅存在于编译器处理期间,如” @Override”;
      • CLASS:存储于类对应的 .class 文件中,为 Annotation 的默认行为;
      • RUNTIME:存储于 class 文件中,并且可由JVM读入;
  • @Documented :标记这些注解是否包含在用户文档 JavaDoc 中,可有可无;
  • @Target - 标记这个注解应该是哪种 Java 成员,可有可无,若无说明可使用于任何地方;
    • ElementType:Enum 枚举类型,用于指定注解声明的位置;
      • TYPE:类、接口(包括注释类型)或枚举声明;
      • FIELD:字段声明(包括枚举常量);
      • METHOD:方法声明;
      • PARAMETER:参数声明;
      • CONSTRUCTOR: 构造方法声明;
      • LOCAL_VARIABLE:局部变量声明;
      • ANNOTATION_TYPE:注释类型声明 ;
      • PACKAGE;
  • @Inherited :某个被标注的类型是被继承的,只能被用来标注“Annotation类型”,如果父类具有该注解,那么其子类也具有该注解;

    2.3 延伸

    2.3.1 Annotation 类

    1. package java.lang.annotation;
    2. public interface Annotation {
    3. boolean equals(Object obj);
    4. int hashCode();
    5. String toString();
    6. Class<? extends Annotation> annotationType();
    7. }
  • 每1个 Annotation 对象,都会有唯一的 RetentionPolicy 属性;

  • 对于每 1 个 Annotation 对象,可以有若干个 ElementType 属性;
  • Annotation 的每一个实现类,都 “和 1 个 RetentionPolicy 关联” 并且 “ 和 1~n 个 ElementType 关联”;

    3. Spring 框架常用注解

    分类整理 详见,表释义整理 详见

    3.1 Bean 相关注解

  • @Inject

  • @Bean
  • Bean 类型描述注解
    • @Component :标准一个普通的 spring Bean 类;
    • @Repository:标注一个 DAO 组件类;
    • @Service:标注一个业务逻辑组件类;
    • @Controller:标注一个控制器组件类;
  • 说明

    • 这几种用法相同,功能相同,其中 Conponent 是笼统意义的组件,其他三种用于区别标识组件的类型;
    • 被注解的 java类 当做 Bean 实例,其中 Bean 实例的注解名称默认是 Bean类 的首字母小写;
    • 可自定义 Bean 名称,但是要求在容器内必须唯一;
    • 在 spring 未来版本中,@Controller,@Service,@Repository 会携带更多语义。并且便于开发和维护;

      3.2 注入 bean 注解

  • 类型

    • @Autowired:属于 Spring 的 org.springframework.beans.factory.annotation 包下,可用于为类的属性、构造器、方法注入 Bean;
      • @Qualifier:@Autowired 注解默认按照类型装配,如果容器中包含多个同一类型的 Bean,那么启动容器时会报找不到指定类型 Bean 的异常,使用 @Qualifier 进行限定,指定注入的 Bean名称
    • @Resource:功能与@Autowired 一致,开发中推荐使用 @Resource;
    • @PostConstruct 和 @PreDestroy 方法:实现初始化和销毁 bean 之前进行的操作;
  • 说明

    • @Autowired 与 @Resource 的区别

      • 提供方: @Autowired 是 Spring 注解;而 @Resource 是 javax.annotation 注解,来自于 JSR-250,J2EE 提供,需要 JDK1.6 及以上;
      • 注入方式: @Autowired 只按照 Type 注入;@Resource 默认按 Name 自动注入,也提供按照 Type 注入;
      • 属性:@Autowired 在默认情况下,要求其依赖的 bean 对象必须存在,否则需设置其 required 属性为false;@Resource 会优先以 name 寻找依赖 bean 对象,若无设置 name,则会默认类、字段或方法名称为 bean 名称,只有在依赖 name 无法找到依赖对象时,才会回退到按 type 寻找;

        3.3 配置文件注解

    • @EnableConfigurationProperties

    • @Configuration
    • @Value
    • @ConfigurationProperties
    • @AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder
    • @ContextConfiguration
    • @Import
    • @ImportResource
    • @Required
    • @PropertySource

      3.4 事务模块注解

  • 类型

    • @EnableTransactionManagement
    • @Transactional:在处理dao层或service层的事务操作时,譬如删除失败时的回滚操作

      3.5 AOP 相关注解

      @EnableAspectJAutoProxy
      @Aspect
      @PointCut
      @Before、@Around、@After
      @AfterReturning
      @AfterThrowing

      3.6 缓存相关注解

      @EnableCaching
      @SessionAttributes
      @Cacheable
      @CacheEvict

      3.7 Spring MVC 注解

    • @Controller :表明该类会作为与前端作交互的控制层组件,通过服务接口定义的提供访问应用程序的一种行为,解释用户的输入,将其转换成一个模型然后将试图呈献给用户;

    • @RequestMapping : 将 url 映射到整个处理类或者特定的处理请求的方法,既可以作用在类级别,也可以作用在方法级别,允许只使用通配符;
    • @RequestBody : @RequestBody是指方法参数应该被绑定到HTTP请求Body上。@ResponseBody与@RequestBody类似,它的作用是将返回类型直接输入到HTTP response body中。
    • @RequestParam :将请求的参数绑定到方法中的参数上,有 required 参数,且默认为 true,若不要求参数必须要传,需设定 required 为 false;
    • @PathVariable : 用于修饰方法的参数,将其变为可供使用的 url 变量(可用于动态绑定);
    • @RestController :控制器实现了REST的API,只为服务于JSON,XML或其它自定义的类型内容,@RestController用来创建REST类型的控制器,与@Controller类型。@RestController就是这样一种类型,它避免了你重复的写@RequestMapping与@ResponseBody
    • @ModelAttribute :@ModelAttribute可以作用在方法或方法参数上,当它作用在方法上时,标明该方法的目的是添加一个或多个模型属性(model attributes)
  • 说明

    1. @Controller
    2. @RequestMapping("/happy")
    3. public class HappyController {
    4. @Autowired
    5. private HappyService happyService;
    6. @RequestMapping(/hello/*)
    7. public void sayHello(){
    8. //请求为 /happy/hello/* 都会进入这个方法!
    9. //例如:/happy/hello/123 /happy/hello/adb
    10. //可以通过get/post 请求
    11. }
    12. @RequestMapping(value="/haha",method=RequestMethod.GET)
    13. public void sayHaHa(
    14. @RequestParam(value = "name", required = false) String name,
    15. @RequestParam(value = "age", required = true) String age
    16. ){
    17. //只能通过get请求
    18. @RequestMapping(value="/happy/{dayid}",method=RequestMethod.GET)
    19. public String findPet(@PathVariable String dayid, Model mode) {
    20. //使用@PathVariable注解绑定 {dayid} 到String dayid
    21. }
    22. }
    23. ...
    24. }

    3.8 Mybatis相关注解

    • @Mapper
    • @MapperScan
    • @Param
    • @Insert、@Select、@Update、@Delete
    • @Results
    • @Result
    • @One
    • @Many

      3.9 SpringBoot 相关注解

    • @SpringBootApplication

    • @EnableAutoConfiguration
    • @SpringBootConfiguration

      4. 自定义注解

      4.1 通用定义

      @Documented
      @Target(ElementType.TYPE)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface MyAnnotation1 {
      参数 }
  • @interface

    • 定义 Annotation 必须使用 @interface ,代表其实现了 java.lang.annotation.Annotation 接口;
    • 与通常意义上 implemented 实现接口的方法不同,Annotation 接口的实现细节都由编译器完成,且通过 @interface 定义注解后,该注解不能继承其他的注解或接口

      4.2 注解的参数

  • 可支持数据类型

    1. 所有基本数据类型(int,float,boolean,byte,double,char,long,short)
    2. String类型
    3. Class类型
    4. enum类型
    5. Annotation类型
    6. 以上所有类型的数组
  • 访问权修饰符:只能用 public 或 默认(default);
  • 注解参数必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为 null,惯用做法是使用 空字符串、0 或负数;
  • 如果只有一个参数成员,最好把参数名称设为”value”,eg:String value() default “”,使用时无需声明;

    • 若有多个参数成员,则在使用时必须要声明对哪个参数初始化,即 参数名 = xxx;

      5. 注解处理器(反射)

      1. // 首先自定义一个注解
      2. @Documented
      3. @Target({ElementType.METHOD,ElementType.FIELD,ElementType.TYPE})
      4. @Retention(RetentionPolicy.RUNTIME)
      5. public @interface MyAnnotation1 {
      6. String getValue() default "no description";
      7. }
      8. // 使用
      9. @MyAnnotation1(getValue = "annotation on class")
      10. public class Demo1 {
      11. @MyAnnotation1(getValue = "annotation on field")
      12. public String name;
      13. @MyAnnotation1(getValue = "annotation on method")
      14. public void hello(){}
      15. @MyAnnotation1()
      16. public void defaultMethod(){}
      17. public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
      18. Class<Demo1> clazz = Demo1.class;
      19. // 获取类上的注解
      20. MyAnnotation1 annotationOnClass = clazz.getAnnotation(MyAnnotation1.class);
      21. System.out.println(annotationOnClass.getValue());
      22. // 获取字段上的注解
      23. Field name = clazz.getField("name");
      24. MyAnnotation1 annotationOnField = name.getAnnotation(MyAnnotation1.class);
      25. System.out.println(annotationOnField.getValue());
      26. // 获取方法上的注解
      27. Method hello = clazz.getMethod("hello", null);
      28. MyAnnotation1 annotationOnMethod = hello.getAnnotation(MyAnnotation1.class);
      29. System.out.println(annotationOnMethod.getValue());
      30. // 获取默认注解
      31. Method defaultMethod = clazz.getMethod("defaultMethod", null);
      32. MyAnnotation1 annotationOnDefaultMethod = defaultMethod.getAnnotation(MyAnnotation1.class);
      33. System.out.println(annotationOnDefaultMethod.getValue());
      34. }
      35. }

      参考

  1. 注解(上)
  2. 注解(下)
  3. 深入理解 Java —— 自定义注解入门
  4. 深入理解 Java —— 注解处理器
  5. 精进Spring—Spring常用注解【经典总结】
  6. Spring 注解大全(自己分类方式)