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

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

        接触过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 应用程序开发提供集成的框架。

    941 引用 • 1458 回帖 • 136 关注
  • 注解
    10 引用 • 22 回帖

相关帖子

欢迎来到这里!

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

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

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

  • 其他回帖
  • zempty 1

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

推荐标签 标签

  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    77 引用 • 1739 回帖 • 1 关注
  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 80 关注
  • RESTful

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

    30 引用 • 114 回帖 • 1 关注
  • 安全

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

    189 引用 • 813 回帖
  • OpenStack

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

    10 引用 • 5 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    73 引用 • 157 回帖
  • Sublime

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

    10 引用 • 5 回帖
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 426 关注
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    324 引用 • 1395 回帖 • 2 关注
  • TextBundle

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

    1 引用 • 2 回帖 • 48 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 1 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 695 关注
  • Wide

    Wide 是一款基于 Web 的 Go 语言 IDE。通过浏览器就可以进行 Go 开发,并有代码自动完成、查看表达式、编译反馈、Lint、实时结果输出等功能。

    欢迎访问我们运维的实例: https://wide.b3log.org

    30 引用 • 218 回帖 • 614 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 22 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖 • 202 关注
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    60 引用 • 287 回帖
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    4 引用 • 16 回帖
  • 音乐

    你听到信仰的声音了么?

    59 引用 • 509 回帖
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 12 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    261 引用 • 662 回帖
  • Eclipse

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

    75 引用 • 258 回帖 • 629 关注
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 451 关注
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 634 关注
  • Sillot

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。
    项目 Github 地址:https://github.com/Hi-Windom/Sillot ,点个免费的 ⭐ 收藏是汐洛更新的最大动力。

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    25 引用 • 23 回帖 • 42 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 31 关注
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 687 关注
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    35 引用 • 200 回帖 • 25 关注