• 随着项目的扩大,配置文件会变得越来越大,越来越臃肿,不利于开发和维护。而注解式编程,则可以大大缩小配置文件。
  • 注解可以放在某个语法单元的头部,表示特定的意义。这个语法单元可以类、接口、属性、方法以及局部变量等。

    1 注解的基础知识

  • 以下是注解知识的讲解,使用@Overide、@Deprecated(过时)、@SuppressWarnings举例。

    1.1 注解的基础语法

  • 注解后是没有分号的。
  • 注解首字母是大写的。因为注解和类、接口是同一级别的。一个注解,后台对应着一个@interface类。
  • 在同一个语法单元上,同一注解只能使用一次。
  • 在注解与语法单元之间可以隔若干空行、注释等非代码内容。

    1.2 注解的注解

    SSH框架之struts2专题4:Struts2注解式开发_第1张图片
    SSH框架之struts2专题4:Struts2注解式开发

  • 打开@Deprecated源码,看到其定义上还有三个注解:@Documented、@Retention、@Target,这三个注解的意义是:
  • @Target:用于指定该注解可以标注的语法类型。CONSTRUCTOR(构造器)、
    LOCAL_VARIABLE(局部变量)、METHOD(方法)、FIELD(属性)、PACKAGE(包)、PARAMETER(参数)、TYPE(类型)。
  • 注意,对于TYPE常量,其意义有两个:一是指该注解可以用在类、接口、枚举等类上;二是指该注解可以作为其他注解的属性值。例如,后面要学到的@Result、@InterceptorRef属性就第二个意思。
  • @Documented:用于指定该注解定义时的注解信息能否显示在javaAPI说明文档中。没有添加的话,使用javadoc生成API文档时就不会将该注解的信息添加到文档中。
  • @RetentionPolicy:这是一个enum类型,共有三个值:SOURCE,CLASS和RUNTIME。
    1、SOURCE:代表这个Annotation类型的信息只会保留在程序源码中,源码如果经过了编译之后,Annotation的数据就会消失,并不会保留在编译好的.class文件中。
    2、CLASS:代表这个Annotation类型的信息除了保留在程序源码里外,同时也会保留在编译好的.class文件中。但是在执行时,并不会把这一些信息加载到虚拟机中。这是Retention的默认值。
    3、表示在源码、编译好的.class文件中保留信息,同时在执行时还会把这些信息加载到JVM中。
  • 举例:@Override中的Retension值为SOURCE,编译成功了就不要这一些检查的信息,相反@Deprecated中的Retention的值为RUNTIME,表示出了在编译时会警告我们使用哪个被Deprecated的方法,在执行的时候也可以查出该方法是否被Deprecated。

    1.3 注解的属性

  • 当某变量被声明了,但是却未被使用;或者某集合在声明或者定义时未加上泛型说明等情况发生时,会在代码下给出警告黄线。Ctrl + 1,可以在代码上添加一个注解@SuppressWarnings()。并且发现,不同的情况,其参数是不同的。
  • 打开其源码,看到其定义与@Deprecated是不同的,其接口体中声明了一个方法String[] value()。那么该注解在使用时必须包含一个属性value,类型为String[]。且该参数没有默认值,即必须给出value的值。
    SSH框架之struts2专题4:Struts2注解式开发_第2张图片
  • 对于注解的属性,需要注意以下几点:
    1、数组问题:
  • 该属性在源码定义时被声明为数组,但是在具体使用时却只要赋予一个值,此时无需将该值再定义为一个数组后赋给该属性。直接将该值赋给该属性即可。例如,对于声明为字符串数组String[]的value属性,可以将字符串String直接赋给该value。
    2、默认值问题:
  • 若某属性再注解定义时声明其默认值,则再注解使用时,可以不为其指定属性值。注解会自动使用其默认值。
    3、value属性问题:
  • 若注解在使用时只需使用其value属性,其他属性要么有默认值,要么该注解只声明了一个value属性,此时,在注解使用时value属性名称可省略,而直接在注解的括号中写出该value属性的值。
    4、无属性问题
  • 有些注解在定义时,是没有属性的,如@Deprecated、@Override都是没有属性声明的,那么在使用时只需要给出注解名称即可。

    2 Struts2注解注意事项

    2.1 Jar包的导入

  • 使用Struts2注解,需要将注解的Jar包struts2-convention-plugin-2.3.24.jar导入。

    2.2 Action包的定义

  • Action类所在包的功能顶层包,必须为action、actions、struts、Struts2中之一。

    2.3 Struts2的配置文件

  • 在使用Struts2注解,主要是用于完成对Action的定义。但是诸如常量定义、拦截器定义等还需要在struts.xml中完成。所以,根据需要确定Struts2配置文件struts.xml是否删除。

    3 Struts2注解详解

    3.1 @ParentPackage

  • 用于指定当前包所要继承的父包。相当于struts.xml中标签的extends属性。查看其源码可知,该注解可放在类型(类、接口、枚举等)与包上。使用时有一个属性value必须赋值。且为String类型,用于指定其所要继承的父包。
    SSH框架之struts2专题4:Struts2注解式开发_第3张图片

    3.2 @Namespace

  • 用于指定该Action所在的命名空间。相当于struts.xml中的namespace属性。不过,需要注意的是,即使不同的Action类的@Namespace的值相同,也不能等同于说这两个Aciton类中的@Action处于同一个Package中。注解中没有配置文件中这个包的概念。
  • 打开其源码,可看到其有一个value属性必须赋值。
    SSH框架之struts2专题4:Struts2注解式开发_第4张图片

    3.3 @Results

  • 用于定义Action类范围的全局视图。若该Action类中定义有多个Action方法,则它们可使用该全局视图。
  • 该全局视图相当于struts.xml中的标签,但是不同于该标签。标签定义的为包范围的全局视图,其可以应用到本中的任意Aciton类定义的的视图中。而Action类范围的全局视图,只能够应用到当前Action类的所有Action方法所定义的@Action的视图中。即使两个Action类的@Namespace值相同,也不能够共享同一个@Results。
  • 查看源码可知,其只能够标注在类和接口等TYPE上,不能够标注在属性、方法上。其属性value为数组,要求必须赋值,其数组元素为另一个注解@Result。
    SSH框架之struts2专题4:Struts2注解式开发_第5张图片

    3.4 @Result

  • 用于定义具体的视图,相当于struts.xml中的标签。查看源码可知,其可作为其他注解的属性值。它有四个属性,且都有默认值。
    SSH框架之struts2专题4:Struts2注解式开发_第6张图片
  • 这四个参数与标签内容的对应关系如下:
    SSH框架之struts2专题4:Struts2注解式开发_第7张图片

    3.5 @Action

  • 用于注解一个Action。可以注解在类、接口与方法上。相当于struts.xml中的标签。注意,并不是定义一个Action类,而是定义一个Action请求响应,即Action类+method。而@Action也是在定义一个Action请求响应。所以,@Action是可以定义在方法上的。
    SSH框架之struts2专题4:Struts2注解式开发_第8张图片
  • @Action中的参数比较多,常用的有三个:
    1、value:指定该Action要响应的请求。相当于标签的name属性。
    2、results:该Action的跳转视图。注意,在Ation类上还定义有全局视图。
    3、interceptorRefs:该Action执行之前要经过的所有拦截器。相当于标签的标签。

    3.6 @InterceptorRef

  • 用于声明所引用的拦截器。相当于struts.xml中标签的子标签。
    SSH框架之struts2专题4:Struts2注解式开发

    3.7 @InterceptorRefs

  • 只能标注在类或接口上,用于定义该类使用的默认拦截器。该注解与@InterceptorRef相结合,相当于struts.xml中的默认拦截器子标签
    SSH框架之struts2专题4:Struts2注解式开发_第9张图片