Spring 里的 Java 基础知识——注解

本贴最后更新于 3055 天前,其中的信息可能已经斗转星移

        接触过Spring开发的或多或少都使用过其注解,写业务代码的同学使用的较频繁的莫过于: @Controller@Service、@Repository。这些注解相比于@Transactional@Cacheable等可以接收较为丰富的元数据,它们扮演的角色更倾向于标记被注解的类在整体架构下的角色,如@Service表征着这个类在架构中是一个服务。查阅它们的源代码,动手尝试自定义一个注解吧

  • 自定义一个注解

package com.qutopia.bixi.spring.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * custom anotation
 *
 * @author choaklin
 * @since 0.1.0
 */
@Documented
// ①声明可以使用该注解的目标类型
@Target(ElementType.TYPE)
// ②声明注解的保留期限
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
    // ③声明注解成员
    String value() default "";
} 
        Java语法规定使用@interface修饰符定义注解类。
        一个注解可以拥有多个成员,成员声明和接口方法声明类似,这里,我们仅定义了一个成员,如所示。成员的声明有以下几点限制: 
            1、成员以无入参无抛出异常的方式声明,如boolean value(String str)、boolean value() throws Exception等方式是非法的
            2、可以通过default为成员指定一个默认值,如String level() default "LOW_LEVEL"、int high() default 2是合法的,当然也可以不指定默认值
            3、成员类型是受限的,合法的类型包括原始类型及其封装类、String、Class、enums、注解类型,以及上述类型的数组类型。如ForumService value()、List foo()是非
                法的

        在①、②处的注解是Java预定义的注解,称为元注解(Meta-Annotation),它们被Java编译器使用,会对注解类的行为产生影响。
        @Target表示该注解可以使用该注解的目标类型
            - TYPE: 类、接口、注解类、Enum声明处
            - FIELD: 类成员变量或枚举常量声明处
            - METHOD: 方法的声明处
            - PARAMETER: 正规的参数声明处
            - CONSTRUCTOR: 构造方法声明处
            - LOCAL_VARIABLE: 局部变量声明处
            - ANNOTATION_TYPE: 注解类声明处
            - PACKAGE: 包声明处
            - TYPE_PARAMETER: 类型(泛型)参数声明处, 1.8新增
            - TYPE_USE: 未知。。。
        @Retention表示注解的保留期限
            - SOURCE: 注解信息仅保留在目标类代码的源码文件中,但对应的字节码文件将不再保留,比如编译时校验的@Override
            - CLASS: 注解信息将进入目标类代码的字节码文件中,但类加载器加载字节码文件时不会将注解加载到JVM中,即运行期不能获取注解信息
            - RUNTIME: 注解信息在目标类加载到JVM后依然保留,在运行期可以通过反射机制读取类中注解信息

        如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=),如@Action("admin")。
        注解类拥有多个成员时,如果仅对value成员进行赋值则也可不使用赋值号,如果同时对多个成员进行赋值,则必须使用赋值号,如DeclareParents (value = "NaiveWaiter", defaultImpl = SmartSeller.class)。
        注解类可以没有成员,没有成员的注解称为标识注解,解释程序以标识注解存在与否进行相应的处理。
 
  • 注解的解释器
        注解是代码的附属信息,它遵循一个基本原则:注解不能直接干扰程序代码的运行,无论增加或删除注解,代码都能够正常运行。对于一个没有配套解释器的注解,基本是毫无作用的。
对于文章开头提到的@Controller@Service、@Repository,它们的解释器是ClassPathBeanDefinitionScanner#scan。所以要想发挥它的作用,就得建立配套的设施。

        在JDK5.0里,Package、Class、Constructor、Method以及Field等反射对象都新增了访问注解信息的方法:<T extends Annotation>T getAnnotation(Class<T> annotationClass),该方法支持通过泛型直接返回注解对象。

package com.qutopia.bixi.spring.annotation;
/**
 * annotation denoting test-class
 *
 * @author choaklin
 * @since 0.1.0
 */
@Action("admin")
public class AdminAction {
    public String index() {
        return "index";
    }
}
package com.qutopia.bixi.spring.annotation;
/**
 * parsers for {@link Action}
 *
 * @author choaklin
 * @since 0.1.0
 */
public class ActionAnnotationParser {
    public static void main(String[] args) {
        //①通过扫描获取到的Class对象
        Class clazz = AdminAction.class;
        //②判断是否存在Action注解
        Action action = (Action)clazz.getAnnotation(Action.class);
        if (action != null) {
            if (action.value() != null) {
                if (action.value().equals("admin")) {
                    System.out.println(">> [AdminAction]是个管理控制器");
                } else {
                    System.out.println(">> [AdminAction]不是个管理控制器");
                }
            } else {
                System.out.println(">> [AdminAction]对于注解[Action]未设置初始值");
            }
        }
    }
}

        运行结果

>> [AdminAction]是个管理控制器




  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    942 引用 • 1459 回帖 • 60 关注
  • 注解
    10 引用 • 22 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • zonghua

    Python 的 装饰器语法(类似 Java 的注解,不过是针对方法的)很好理解。

  • 其他回帖
  • zempty 1

    感动ing 好久没有看到这么优质的文章!请容我小小的激动一下

推荐标签 标签

  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    70 引用 • 533 回帖 • 759 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    123 引用 • 168 回帖 • 1 关注
  • SendCloud

    SendCloud 由搜狐武汉研发中心孵化的项目,是致力于为开发者提供高质量的触发邮件服务的云端邮件发送平台,为开发者提供便利的 API 接口来调用服务,让邮件准确迅速到达用户收件箱并获得强大的追踪数据。

    2 引用 • 8 回帖 • 465 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 1 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 2 关注
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    75 引用 • 258 回帖 • 634 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    165 引用 • 594 回帖 • 1 关注
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    88 引用 • 1234 回帖 • 425 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    11 引用 • 90 回帖 • 1 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 2 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 598 回帖
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖 • 1 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    5 引用 • 13 回帖 • 3 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 268 回帖 • 88 关注
  • CodeMirror
    1 引用 • 2 回帖 • 130 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    116 引用 • 99 回帖 • 235 关注
  • CongSec

    本标签主要用于分享网络空间安全专业的学习笔记

    6 引用 • 1 回帖 • 1 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 232 回帖
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1081 引用 • 3459 回帖 • 232 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 3 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    287 引用 • 4484 回帖 • 669 关注
  • 安全

    安全永远都不是一个小问题。

    200 引用 • 816 回帖
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 370 关注
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖 • 3 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 47 关注