• SpringMVC框架——JDK注解


    SpringMVC框架中提倡运用注解技术来简化xml配置,也是当下Java编程的趋势和潮流,值得用功学习。

    这一章总结Java JDK中的注解

    关于注解的学习博客网上有很多,各位可以去看看,我在这里只总结自己的学习理解。

    一、注解的概念
    1.注解是JavaJDK1.5引入的一种新的数据类型,它的本质其实是一个特殊的接口。

    这种特殊性在于:
    (1)直接继承java.lang.anotation.Annotation接口,这意味着注解接口没有子接口;
    (2)表现形式:public @interface Xxx
    @的含义是: public interfac Xxx extends Annotation
    (3)注解接口不需要程序员实现,因为JVM在程序运行时为注解接口动态产生代理类及其对象;

    2.注解的定义形式:
    public @interface AnnotationName{
    元素声明1;
    元素声明2;
    ...
    }
    其中,元素声明通常有如下两种形式:
    (1) 元素类型 元素名称()
    (2) 元素类型 元素名称() default value;

    3.注解接口中的元素实质:
    (1)注解接口中的元素声明实际上是方法的声明;
    (2)注解接口中的方法没有任何参数;
    (3)注解接口中的方法有返回值,可以通过default value,为方法指定默认的返回值;

    4.注解元素的类型为下列之一:
    (1)一个基本类型(int short long byte char double float boolean);
    (2)String类型
    (3)enum类型
    (4)Class类型
    (5)注解类型
    (6)由上述类型组成的数组;5.举例:注解接口定义:

    public @interface BugReport{
    String assignedTo() default "none";
    int severity() default 0;
    }

    二、注解的使用
    1.注解作为修饰符用来标注程序元素;
    2.程序元素在java.lang.annotation包下的ElementType枚举类有明确的定义:
    (1)PACKAGE 包
    (2)TYPE 类和普通接口
    (3)ANNOTATION_TYPE 注解接口
    (4)FIELD 成员变量
    (5)CONSTRUCTOR 构造器
    (6)METHOD 方法
    (7)PARAMETER 方法参数
    (8)LOCAL_VARIABLE 方法局部变量
    3.注解的标注格式
    @AnnotationName(元素名称1=值1,元素名称2=值2,...)
    举例:
    @BugReport(assignedTo="Wangda", severity=10);

    如果某个元素在使用时未指明,则使用声明时的默认值,例如:
    @BugReport(assignedTo="Lifen");
    元素serverity的值是0。
    @BugReport
    4.注解使用的进一步说明:
    (1)标记型注解,
    例如: @BugReport
    如下两种情况:
    ①注解接口中可能没有定义任何元素;
    ②注解使用元素的默认值
    (2)单值注解的简洁格式
    如果注解中的元素名称是value,且没有其它元素,则使用时可以忽略元素的名称及等号。
    例如:一个注解接口如下:
    public @interface ActionListenerFor{
    String value();
    }
    使用时,可以有两种形式:
    @ActionListernerFor(value="yelloButton")
    或者:
    @ActionListenerFor("yellowButton")
    (3)注解元素值是一个数组
    例如:
    public @interface BugReport{
    String[] reportedBy();
    }
    使用时,需要使用{}表示数组值
    @BugReport(reportedBy={"wangda","qiangui"})
    如果数组中只有一个单值,也可以省略{}
    @BugReport(reportedBy="Joe")等价于@BugReport(reportedBy={"Joe"})

    三、JDK中所定义的注解
    [①元注解②规则注解③和依赖注入相关的注解]
    1.元注解(位于java.lang.annotation包下)
    元注解是注解注解的注解。(很绕。。。)

    注解是用来注解程序中元素的,元注解就是来限制注解的。
    (Ⅲ)JDK定义了哪些元注解?
    (1)@Documented
    ①用途
    注解进入文档,JavaDoc文档工具可以将注解提取到文档中。
    ②定义
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Documented {
    }

    解释:注解进文档;该注解的作用保留到程序运行时;该注解标注的是ANNOTATION_TYPE即标注类型的元素。

    (2)@Inherited
    ①用途
    继承的子类自动拥有父类的注解;
    ②定义
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Inherited {
    }

    (3)@Retention(enumValue)
    ①用途
    指明程序中的注解保留到哪一个阶段;有三个阶段:source、class和runtime,
    被称为保留策略。
    ②注解的保留策略
    RetentionPolicy是枚举类,在该类中定义了注解的3种保留策略:
    (a)RUNTIME √
    注解保留到程序运行时,JVM通过反射产生注解的代理对象;
    (b)CLASS
    注解保留到编译期,编译器根据注解标注,判断是否显示警告;
    但JVM不载入,因此运行时无效;
    (c)SOURCE
    注解只保留在源码中,在class文件中不存在;
    ③定义
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Retention {
    RetentionPolicy value();
    }

    (4)@Target({enumValue1, enumValue2, ...})
    ①用途
    指明注解所标注的程序元素,程序元素在ElementType枚举类中进行了定义,
    参考前面
    ②定义
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
    public @interface Target {
    ElementType[] value();
    }

    2.规则注解(位于java.lang包下):
    (1)@Override
    ①定义:
    @Target(value=METHOD)
    @Retention(value=SOURCE)
    public @interface Override
    ②用途:
    如果方法利用此注解进行标注但没有重写超类方法,则编译器会生成一条错误消息。

    解释:这个通常用于辅助检查,因为有事子类重写父类方法可能出现拼写错误的失误,这是不会报错,但程序肯定会出问题。
    (2)@Deprecated
    ①定义:
    @Documented
    @Retention(value=RUNTIME)
    public @interface Deprecated
    ②用途:
    用 @Deprecated 所标注的程序元素,不鼓励程序员使用;如果强行使用,编译器会发出警告。
    这个注解与Java文档标签@deprecated具有同等的功效。

    (3)@SuppressWarnings({"value1","value2",...})
    ①定义
    @Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
    @Retention(value=SOURCE)
    public @interface SuppressWarnings{
    String[] value()
    }
    ②用途:
    抑制编译器所产生的警告信息
    例如:@SuppressWarnings({"unchecked","rawtypes","serial"})
    ③demo
    参考:E:海淀英才Workspace->spring04_annotation->src->test

    3.和依赖注入相关的注解(位于javax.annotation包下)
    (1)@Resource(name="value1")
    ①定义:
    @Target(value={TYPE,FIELD,METHOD})
    @Retention(value=RUNTIME)
    public @interface Resource{
     String name() default ""
    Class type() default Object.class
    }
    ②用途——实施依赖注入
    (a)标注成员变量,
    注入的对象,默认名称为字段名;
    (b)标注方法
    通过方法参数注入的对象,默认名称为JavaBean的属性名称;
    (c)标注类
    没有默认值,必须指明所注入对象的名称
    ③在Spring框架中使用
    Spring将@Resource注解的name元素的值解析为bean的名字,而type元素的值解析为bean的类型。
    所以如果使用name元素,则使用byName的自动注入策略,而使用type元素时则使用byType自动注入策略。
    默认情况下使用byName自动注入策略。

    demo:

     1 import javax.annotation.PostConstruct;
     2 import javax.annotation.PreDestroy;
     3 import javax.annotation.Resource;
     4 
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.beans.factory.annotation.Qualifier;
     7 import org.springframework.context.annotation.Scope;
     8 import org.springframework.stereotype.Component;
     9 import org.springframework.stereotype.Service;
    10 
    11 @Component//该注解会自动注册名为"useBean"的对象
    12 public class UseBean {
    13     
    14 //    @Resource(name="zhHelloBean")//通过该注解引入依赖对象,按id注入名为zhHelloBean的对象
    15 
    16     //这种也是注入依赖对象,不同于上述注解,这个需要两个注解来设置“自动装配”和“按id装入对象”
    17     @Autowired
    18     @Qualifier(value="zhHelloBean")
    19     private IHelloBean hello;
    20     
    21     public IHelloBean getHello() {
    22         return hello;
    23     }
    24 
    25     public void show(){
    26         System.out.println("调用"+
    27                 hello.getClass().getName()+
    28                 "对象的sayHello方法:");
    29         hello.sayHello();
    30     }
    31     
    32 }
    33 
    34 
    35 import org.springframework.context.ApplicationContext;
    36 import org.springframework.context.support.ClassPathXmlApplicationContext;
    37 
    38 public class UseBeanTest {
    39     //使用注解技术可以注册bean并通过框架获取对象
    40     private static final String CONFIG=
    41         "anno/demo2/applicationContext.xml";
    42     public static void main(String[] args) {
    43         ClassPathXmlApplicationContext ac=
    44             new ClassPathXmlApplicationContext(CONFIG);
    45         UseBean ub1=(UseBean)ac.getBean("useBean");
    46         UseBean ub2=(UseBean)ac.getBean("useBean");
    47         System.out.println("ub1==ub2?"+(ub1==ub2));
    48         ub2.show();
    49         ac.close();
    50     }
    51 
    52 }

    而在框架的配置文件中,我们只需一句语句就能启动配置。这句代码就是告诉框架扫描指定位置的包,根据注解创建对象,注册到容器中

    <!-- 扫描指定包下程序,根据注解创建对象,并注册到容器中 -->
        <context:component-scan base-package="anno.demo2" />

    节省了大量配置语句

    (2)@PostConstruct
    ①定义
    @Documented
    @Retention(value=RUNTIME)
    @Target(value=METHOD)
    public @interface PostConstruct
    ②用途:
    在对象的依赖关系注入之后,所需要进一步执行的初始化方法。要求被标注的方法不能有参数,而且无返回值。
    参照:spring04_annotation->anno.demo3.UseBean.java
    (3)@PreDestroy
    ①定义:
    @Documented
    @Retention(value=RUNTIME)
    @Target(value=METHOD)
    public @interface PreDestroy
    ②用途:
    在容器销毁对象前所执行的方法,目的是为了释放资源。要求被标注的方法不能有参数,而且无返回值。

  • 相关阅读:
    主流NoSQL数据库评测之HBase
    Java Io原理及应用
    Facebook:HBase每月存储1350亿条信息
    Facebook为何选择云计算开源Hadoop
    ActiveMq配置解析
    主流NoSQL数据库评测之HandlerSocket
    软件类官方网站收藏
    Mongodb 更新失败解决方案
    主流NoSQL数据库全方位评测:MongoDB
    java为什么比c++要慢?以及如何提高java的效率
  • 原文地址:https://www.cnblogs.com/cxy2016/p/8506302.html
Copyright © 2020-2023  润新知