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

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

        接触过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 引用 • 1458 回帖 • 106 关注
  • 注解
    10 引用 • 22 回帖

相关帖子

欢迎来到这里!

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

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

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

  • 其他回帖
  • zonghua

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

推荐标签 标签

  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    330 引用 • 1716 回帖 • 1 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    495 引用 • 1386 回帖 • 328 关注
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 139 关注
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 608 关注
  • Wide

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

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

    30 引用 • 218 回帖 • 617 关注
  • Gitea

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

    4 引用 • 16 回帖 • 1 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 193 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 677 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 97 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 134 关注
  • ActiveMQ

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

    19 引用 • 13 回帖 • 640 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 598 回帖
  • wolai

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

    2 引用 • 14 回帖
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    21 引用 • 58 回帖
  • CodeMirror
    1 引用 • 2 回帖 • 124 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 350 关注
  • gRpc
    11 引用 • 9 回帖 • 54 关注
  • SVN

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

    29 引用 • 98 回帖 • 690 关注
  • GAE

    Google App Engine(GAE)是 Google 管理的数据中心中用于 WEB 应用程序的开发和托管的平台。2008 年 4 月 发布第一个测试版本。目前支持 Python、Java 和 Go 开发部署。全球已有数十万的开发者在其上开发了众多的应用。

    14 引用 • 42 回帖 • 706 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 1 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    126 引用 • 1699 回帖
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 606 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    198 引用 • 120 回帖