SpringMVC 常见注解

详解SpringMVC4常用的那些注解http://favccxx.blog.51cto.com/2890523/1582185

SpringMVC常见注解http://qing.blog.sina.com.cn/3225985210/c048a0ba33003w90.html

1•@Controller

2•@Service

3•@Autowired

4•@RequestMapping

5•@RequestParam

6•@ModelAttribute

7•@Cacheable

8•@CacheFlush

9•@Resource

10•@PostConstruct

11•@PreDestroy

12•@Repository

13•@Component(不推荐使用)

14•@Scope

15•@SessionAttributes

16•@InitBinder

17•@Required

18•@Qualifier

19•@PathVariable

20•@Valid

21•@AttributeOverride

22•@Column

1•@Controller

例如

@Controller

publicclassSoftCreateControllerextendsSimpleBaseController{}

或者

@Controller("softCreateController")

说明

@Controller负责注册一个bean到spring上下文中,bean的ID默认为类名称开头字母小写

2•@Service

例如

@Service

publicclassSoftCreateServiceImplimplementsISoftCreateService{}

或者

@Service("softCreateServiceImpl")

说明

@Service负责注册一个bean到spring上下文中,bean的ID默认为类名称开头字母小写

3•@Autowired

例如

@Autowired

privateISoftPMServicesoftPMService;

或者

@Autowired(required=false)

privateISoftPMServicesoftPMService=newSoftPMServiceImpl();

说明

@Autowired根据bean类型从spring上线文中进行查找,注册类型必须唯一,否则报异常。与@Resource的区别在于,@Resource允许通过bean名称或bean类型两种方式进行查找@Autowired(required=false)表示,如果spring上下文中没有找到该类型的bean时,才会使用newSoftPMServiceImpl();

@Autowired标注作用于Map类型时,如果Map的key为String类型,则Spring会将容器中所有类型符合Map的value对应的类型的Bean增加进来,用Bean的id或name作为Map的key。

@Autowired还有一个作用就是,如果将其标注在BeanFactory类型、ApplicationContext类型、ResourceLoader类型、ApplicationEventPublisher类型、MessageSource类型上,那么Spring会自动注入这些实现类的实例,不需要额外的操作。

4•@RequestMapping

@Controller

@RequestMapping("/bbtForum.do")

publicclassBbtForumController{

@RequestMapping(params="method=listBoardTopic")

publicStringlistBoardTopic(inttopicId,Useruser){}

}

方法

@RequestMapping("/softpg/downSoftPg.do")

@RequestMapping(value="/softpg/ajaxLoadSoftId.do",method=POST)

@RequestMapping(value="/osu/product/detail.do",params={"modify=false"},method=POST)

说明

@RequestMapping可以声明到类或方法上

参数绑定说明

如果我们使用以下的URL请求:

http://localhost/bbtForum.do?method=listBoardTopic&topicId=1&userId=10&userName=tom

topicIdURL参数将绑定到topicId入参上,而userId和userNameURL参数将绑定到user对象的userId和userName属性中。和URL请求中不允许没有topicId参数不同,虽然User的userId属性的类型是基本数据类型,但如果URL中不存在userId参数,Spring也不会报错,此时user.userId值为0。如果User对象拥有一个dept.deptId的级联属性,那么它将和dept.deptIdURL参数绑定。

5•@RequestParam

参数绑定说明

@RequestParam("id")

http://localhost/bbtForum.do?method=listBoardTopic&id=1&userId=10&userName=tom

listBoardTopic(@RequestParam("id")inttopicId,Useruser)中的topicId绑定到id这个URL参数,那么可以通过对入参使用@RequestParam注解来达到目的

@RequestParam(required=false):参数不是必须的,默认为true

@RequestParam(value="id",required=false)

请求处理方法入参的可选类型

*Java基本数据类型和String

默认情况下将按名称匹配的方式绑定到URL参数上,可以通过@RequestParam注解改变默认的绑定规则

*request/response/session

既可以是ServletAPI的也可以是PortletAPI对应的对象,Spring会将它们绑定到Servlet和Portlet容器的相应对象上

*org.springframework.web.context.request.WebRequest

内部包含了request对象

*java.util.Locale

绑定到request对应的Locale对象上

*java.io.InputStream/java.io.Reader

可以借此访问request的内容

*java.io.OutputStream/java.io.Writer

可以借此操作response的内容

*任何标注了@RequestParam注解的入参

被标注@RequestParam注解的入参将绑定到特定的request参数上。

*java.util.Map/org.springframework.ui.ModelMap

它绑定SpringMVC框架中每个请求所创建的潜在的模型对象,它们可以被Web视图对象访问(如JSP)

*命令/表单对象(注:一般称绑定使用HTTPGET发送的URL参数的对象为命令对象,而称绑定使用HTTPPOST发送的URL参数的对象为表单对象)

它们的属性将以名称匹配的规则绑定到URL参数上,同时完成类型的转换。

而类型转换的规则可以通过@InitBinder注解或通过HandlerAdapter的配置进行调整

*org.springframework.validation.Errors/org.springframework.validation.BindingResult

为属性列表中的命令/表单对象的校验结果,注意检验结果参数必须紧跟在命令/表单对象的后面

*org.springframework.web.bind.support.SessionStatus

可以通过该类型status对象显式结束表单的处理,这相当于触发session清除其中的通过@SessionAttributes定义的属性

请求处理方法返回值的可选类型

*void

此时逻辑视图名由请求处理方法对应的URL确定,如以下的方法:

@RequestMapping("/welcome.do")

publicvoidwelcomeHandler(){}

对应的逻辑视图名为“welcome”

*String

此时逻辑视图名为返回的字符,如以下的方法:

@RequestMapping(method=RequestMethod.GET)

publicStringsetupForm(@RequestParam("ownerId")intownerId,ModelMapmodel){

Ownerowner=this.clinic.loadOwner(ownerId);

model.addAttribute(owner);

return"ownerForm";

}

对应的逻辑视图名为“ownerForm”

*org.springframework.ui.ModelMap

和返回类型为void一样,逻辑视图名取决于对应请求的URL,如下面的例子:

@RequestMapping("/vets.do")

publicModelMapvetsHandler(){

returnnewModelMap(this.clinic.getVets());

}

对应的逻辑视图名为“vets”,返回的ModelMap将被作为请求对应的模型对象,可以在JSP视图页面中访问到。

*ModelAndView

当然还可以是传统的ModelAndView。

6•@ModelAttribute

作用域:request

例如

@RequestMapping("/base/userManageCooper/init.do")

publicStringhandleInit(@ModelAttribute("queryBean")ManagedUsersUser,Modelmodel,){

或者

@ModelAttribute("coopMap")//将coopMap返回到页面

publicMap<Long,CooperatorInfo>coopMapItems(){}

说明

@ModelAttribute声明在属性上,表示该属性的value来源于model里"queryBean",并被保存到model里

@ModelAttribute声明在方法上,表示该方法的返回值被保存到model里

•@Cacheable和@CacheFlush

7•@Cacheable:声明一个方法的返回值应该被缓存

例如:@Cacheable(modelid="testCaching")

8•@CacheFlush:声明一个方法是清空缓存的触发器

例如:@CacheFlush(modelid="testCaching")

说明

9•@Resource

例如

@Resource

privateDataSourcedataSource;//injectthebeannamed'dataSource'

或者

@Resource(name="dataSource")

@Resource(type=DataSource.class)

说明

@Resource默认按bean的name进行查找,如果没有找到会按type进行查找,

此时与@Autowired类似

在没有为@Resource注解显式指定name属性的前提下,如果将其标注在BeanFactory类型、ApplicationContext类型、ResourceLoader类型、ApplicationEventPublisher类型、MessageSource类型上,那么Spring会自动注入这些实现类的实例,不需要额外的操作。此时name属性不需要指定(或者指定为""),否则注入失败;

•@PostConstruct和@PreDestroy

10•@PostConstruct

在方法上加上注解@PostConstruct,这个方法就会在Bean初始化之后被Spring容器执行

(注:Bean初始化包括,实例化Bean,并装配Bean的属性(依赖注入))。

11•@PreDestroy

在方法上加上注解@PreDestroy,这个方法就会在Bean被销毁前被Spring容器执行。

12•@Repository

与@Controller、@Service类似,都是向spring上下文中注册bean,不在赘述。

13•@Component(不推荐使用)

@Component是所有受Spring管理组件的通用形式,Spring还提供了更加细化的注解形式:@Repository、@Service、@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean。

目前版本(2.5)中,这些注解与@Component的语义是一样的,完全通用,在Spring以后的版本中可能会给它们追加更多的语义。所以,我们推荐使用@Repository、@Service、@Controller来替代@Component。

14•@Scope

例如

@Scope("session")

@Repository()

publicclassUserSessionBeanimplementsSerializable{}

说明

在使用XML定义Bean时,可以通过bean的scope属性来定义一个Bean的作用范围,

同样可以通过@Scope注解来完成

@Scope中可以指定如下值:

singleton:定义bean的范围为每个spring容器一个实例(默认值)

prototype:定义bean可以被多次实例化(使用一次就创建一次)

request:定义bean的范围是http请求(springMVC中有效)

session:定义bean的范围是http会话(springMVC中有效)

global-session:定义bean的范围是全局http会话(portlet中有效)

15•@SessionAttributes

说明

Spring允许我们有选择地指定ModelMap中的哪些属性需要转存到session中,

以便下一个请求属对应的ModelMap的属性列表中还能访问到这些属性。

这一功能是通过类定义处标注@SessionAttributes注解来实现的。

@SessionAttributes只能声明在类上,而不能声明在方法上。

例如

@SessionAttributes("currUser")//将ModelMap中属性名为currUser的属性

@SessionAttributes({"attr1","attr2"})

@SessionAttributes(types=User.class)

@SessionAttributes(types={User.class,Dept.class})

@SessionAttributes(types={User.class,Dept.class},value={"attr1","attr2"})

16•@InitBinder

说明

如果希望某个属性编辑器仅作用于特定的Controller,

可以在Controller中定义一个标注@InitBinder注解的方法,

可以在该方法中向Controller了注册若干个属性编辑器

例如

@InitBinder

publicvoidinitBinder(WebDataBinderbinder){

SimpleDateFormatdateFormat=newSimpleDateFormat("yyyy-MM-dd");

dateFormat.setLenient(false);

binder.registerCustomEditor(Date.class,newCustomDateEditor(dateFormat,false));

}

17•@Required

例如

@required

publicsetName(Stringname){}

说明

@required负责检查一个bean在初始化时其声明的set方法是否被执行,当某个被标注了@Required的Setter方法没有被调用,则Spring在解析的时候会抛出异常,以提醒开发者对相应属性进行设置。@Required注解只能标注在Setter方法之上。因为依赖注入的本质是检查Setter方法是否被调用了,而不是真的去检查属性是否赋值了以及赋了什么样的值。如果将该注解标注在非setXxxx()类型的方法则被忽略。

18•@Qualifier

例如

@Autowired

@Qualifier("softService")

privateISoftPMServicesoftPMService;

说明

使用@Autowired时,如果找到多个同一类型的bean,则会抛异常,此时可以使用@Qualifier("beanName"),明确指定bean的名称进行注入,此时与@Resource指定name属性作用相同。

19•@PathVariable

@PathVariable是用来对指定请求的URL路径里面的变量

eg:Java代码@RequestMapping(value="form/{id}/apply",method={RequestMethod.PUT,RequestMethod.POST}){id}

在这个请求的URL里就是个变量,可以使用@PathVariable来获取

20•@valid

@ValidProductionproduction//实体设置+类+类的引用直接将页面传过来的production对象中的信息封装到里面去了

21•@AttributeOverride

@AttributeOverride表示属性的映射,而@AttributeOverrides由多个@AttributeOverride注释组成,每个@AttributeOverride表示属性的映射,它的定义如以下所示:

@Target({TYPE,METHOD,FIELD})@Retention(RUNTIME)

public@interfaceAttributeOverride{

Stringname();

Columncolumn();

}

在使用@AttributeOverride注释应注意以下几方面的问题:

☆name属性表示嵌入式类中的属性名称。

☆column属性表示,所嵌入的实体类中的列定义,其中@Column标记表示的意义见第22项。

☆例如将tb_customer表中的customer_zip字段映射为Address中的属性zip。代码如下所示:

@AttributeOverride(name="zip",

column=@Column(name="customer_zip")

)

☆使用嵌入式类的好处是:多个实体中都可以共享一个嵌入式类,方便了对实体的操作。例如现在ContactEO也嵌入Address类,就很方便的映射为以下所示:

publicclassCustomerEOimplementsSerializable{

privateIntegerid;

privateStringname;

privateStringnickname;

……getter和setter方法省略

privateAddressaddress;

@Embedded

@AttributeOverrides({

@AttributeOverride(name="zip",column=@Column(name="contact_zip")),

@AttributeOverride(name="line1",column=@Column(name="contact_line1")),

})

publicAddressgetAddress(){

returnaddress;

}

publicvoidsetAddress(Addressaddress){

this.address=address;

}

}

22•@Column

@Column标记表示所持久化属性所映射表中的字段,该注释的属性定义如下:

@Target({METHOD,FIELD})@Retention(RUNTIME)

public@interfaceColumn{

Stringname()default"";

booleanunique()defaultfalse;

booleannullable()defaulttrue;

booleaninsertable()defaulttrue;

booleanupdatable()defaulttrue;

StringcolumnDefinition()default"";

Stringtable()default"";

intlength()default255;

intprecision()default0;

intscale()default0;

}

在使用此@Column标记时,需要注意以下几个问题:

l此标记可以标注在getter方法或属性前,例如以下的两种标注方法都是正确的:

标注在属性前:

@Entity

@Table(name="contact")

publicclassContactEO{

@Column(name="contact_name")

privateStringname;

}

标注在getter方法前:

@Entity

@Table(name="contact")

publicclassContactEO{

@Column(name="contact_name")

publicStringgetName(){

returnname;

}

}

提示:JPA规范中并没有明确指定那种标注方法,只要两种标注方式任选其一都可以。这根据个人的喜好来选择,笔者习惯使用第二种方法。

lunique属性表示该字段是否为唯一标识,默认为false。如果表中有一个字段需要唯一标识,则既可以使用该标记,也可以使用@Table标记中的@UniqueConstraint。

lnullable属性表示该字段是否可以为null值,默认为true。

linsertable属性表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值。

lupdatable属性表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable和updatable属性一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。

lcolumnDefinition属性表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。

ltable属性表示当映射多个表时,指定表的表中的字段。默认值为主表的表名。有关多个表的映射将在本章的5.6小节中详细讲述。

llength属性表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。

lprecision属性和scale属性表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数。

下面举几个小例子:

示例一:指定字段“contact_name”的长度是“512”,并且值不能为null。

privateStringname;

@Column(name="contact_name",nullable=false,length=512)

publicStringgetName(){

returnname;

}

创建的SQL语句如下所示。

CREATETABLEcontact(

idintegernotnull,

contact_namevarchar(512)notnull,

primarykey(id)

)

示例二:指定字段“monthly_income”月收入的类型为double型,精度为12位,小数点位数为2位。

privateBigDecimalmonthlyIncome;

@Column(name="monthly_income",precision=12,scale=2)

publicBigDecimalgetMonthlyIncome(){

returnmonthlyIncome;

}

创建的SQL语句如下所示。

CREATETABLEcontact(

idintegernotnull,

monthly_incomedouble(12,2),

primarykey(id)

)

示例三:自定义生成CLOB类型字段的SQL语句。

privateStringname;

@Column(name="contact_name",columnDefinition="clobnotnull")

publicStringgetName(){

returnname;

}

生成表的定义SQL语句如下所示。

CREATETABLEcontact(

idintegernotnull,

contact_nameclob(200)notnull,

primarykey(id)

)

其中,加粗的部分为columnDefinition属性设置的值。若不指定该属性,通常使用默认的类型建表,若此时需要自定义建表的类型时,可在该属性中设置。

提示:通过Entity定义生成表,还是通过表配置Entity,这两种ORM的策略。有关两种方法的映射策略好坏,将在本书的章节中“JPA工具的使用”一章进行详细的比较。

示例四:字段值为只读的,不允许插入和修改。通常用于主键和外键。

privateIntegerid;

@Column(name="id",insertable=false,updatable=false)

publicIntegergetId(){

returnid;

}

相关推荐