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 
      ②用途:
	在容器销毁对象前所执行的方法,目的是为了释放资源。要求被标注的方法不能有参数,而且无返回值。
 
                    
                
 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号