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;
}