1. 註冊註解處理器
命名空間<context:component-scan/>
首先,如果要使註解工作,則必須配置component-scan 。該配置的功能爲:啓動包掃描功能,以便註冊帶有@Controller、@Service、@repository、@Component等註解的類成爲spring的bean。例:<context:component-scanbase-package="com.tgb.web"/>
base-package 屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會被處理。還允許定義過濾器將基包下的某些類納入或排除。
Spring支持以下4種類型的過濾方式:
1) 註解org.example.SomeAnnotation 將所有使用SomeAnnotation註解的類過濾出來
2) 類名指定org.example.SomeClass 過濾指定的類
3) 正則表達式com.kedacom.spring.annotation.web..* 通過正則表達式過濾一些類
4) AspectJ 表達式 org.example..*Service+ 通過AspectJ 表達式過濾一些類
正則表達式的過濾方式舉例:
註解的過濾方式舉例:
2. 啓動Spring MVC 的註解功能,完成請求和註解POJO 的映射
2.1 @Controller—表示控制器
舉例:
@Controller
public class SoftCreateController extendsSimpleBaseController {}
或者:
@Controller("softCreateController")
說明:
@Controller負責註冊一個bean到spring上下文中,bean的ID默認爲類名稱開頭字母小寫
注意:
和Struts1一樣,Spring的Controller是Singleton的。這就意味着會被多個請求線程共享。因此,我們將控制器設計成無狀態類。
在spring 3.0中,通過@controller標註即可將class定義爲一個controller類。有以上可知,爲使spring能找到定義爲controller的bean,需要在spring-context配置文件中增加如下定義:
<context:component-scanbase-package="com.sxt.web"/>
注:實際上,使用@component(下面有介紹),也可以起到@Controller同樣的作用。
----------------------------------------------------------------------------------------------------------------------
2.2 @Service—表示業務處理層[一般在serviceImpl]
舉例:
@ Service
public class SoftCreateServiceImpl implements ISoftCreateService{}
或者:
@Service("softCreateServiceImpl")
說明:
@Service負責註冊一個bean到spring上下文中,bean的ID默認爲類名稱開頭字母小寫
2.3 @Repository—表示持久層[一般在daoImpl]
與@Controller、@Service類似,都是向spring上下文中註冊bean,不在贅述。
----------------------------------------------------------------------------------------------------------------------
2.4 @Component(不推薦使用)—當你的類不清楚是哪一層的時候使用該註解
@Component
@Component是所有受Spring管理組件的通用形式,Spring還提供了更加細化的註解形式: @Repository、@Service、@Controller,它們分別對應存儲層Bean,業務層Bean,和展示層Bean。
目前版本(2.5)中,這些註解與@Component的語義是一樣的,完全通用,在Spring以後的版本中可能會給它們追加更多的語義。所以,我們推薦使用@Repository、@Service、@Controller來替代@Component。
----------------------------------------------------------------------------------------------------------------------
2.5 @Resource
例如:
@Resource
private DataSource dataSource; // injectthe bean named ‘dataSource‘
或者:
@Resource(name="dataSource")
@Resource(type=DataSource.class)
說明:
@Resource默認按bean的name進行查找,如果沒有找到會按type進行查找,此時與@Autowired類似
在沒有爲 @Resource註解顯式指定 name屬性的前提下,如果將其標註在BeanFactory類型、ApplicationContext類型、ResourceLoader類型、ApplicationEventPublisher類型、MessageSource類型上,那麼 Spring 會自動注入這些實現類的實例,不需要額外的操作。此時name屬性不需要指定(或者指定爲""),否則注入失敗;
----------------------------------------------------------------------------------------------------------------------
2.6 @Autowired
例如:
@Autowired
private ISoftPMService softPMService;
或者:
@Autowired(required=false)
private ISoftPMService softPMService = newSoftPMServiceImpl();
說明:
? @Autowired根據bean類型從spring上線文中進行查找,註冊類型必須唯一,否則報異常。與@Resource的區別在於,@Resource允許通過bean名稱或bean類型兩種方式進行查找@Autowired(required=false)表示,如果spring上下文中沒有找到該類型的bean時,纔會使用new SoftPMServiceImpl();
? @Autowired標註作用於 Map類型時,如果 Map的 key 爲 String類型,則 Spring會將容器中所有類型符合 Map的 value 對應的類型的 Bean增加進來,用 Bean的 id或 name作爲 Map的 key。
? @Autowired還有一個作用就是,如果將其標註在 BeanFactory類型、ApplicationContext類型、ResourceLoader類型、ApplicationEventPublisher類型、MessageSource類型上,那麼 Spring會自動注入這些實現類的實例,不需要額外的操作。
----------------------------------------------------------------------------------------------------------------------
2.7 @RequestMapping
類:
方法:
說明:
@RequestMapping可以聲明到類或方法上
實例:
package com.sxt.web;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.sxt.service.UserService;
@Controller
@RequestMapping("/user.do")
public class UserController {
@Resource
private UserService userService;
//http://localhost:8080/springmvc02/user.do?method=reg&uname=zzzz
@RequestMapping(params="method=reg")
public String reg(String uname) {
System.out.println("HelloController.handleRequest()");
userService.add(uname);
return "index";
}
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
參數綁定說明:
如果我們使用以下的 URL請求:
http://localhost/bbtForum.do?method=listBoardTopic&topicId=1&userId=10&userName=tom
topicIdURL參數將綁定到topicId入參上,而userId和userName URL參數將綁定到user對象的userId和userName屬性中。和URL請求中不允許沒有topicId參數不同,雖然User的userId屬性的類型是基本數據類型,但如果URL中不存在userId參數,Spring也不會報錯,此時user.userId值爲0。如果 User 對象擁有一個dept.deptId的級聯屬性,那麼它將和dept.deptId URL參數綁定。
----------------------------------------------------------------------------------------------------------------------
2.8 @RequestParam
說明:
一般用於將指定的請求參數付給方法中形參。示例代碼如下:
@RequestMapping(params="method=reg5")
public String reg5(@RequestParam("name")String uname,ModelMap map) {
System.out.println("HelloController.handleRequest()");
System.out.println(uname);
return "index";
}
這樣,就會將name參數的值付給uname。當然,如果請求參數名稱和形參名稱保持一致,則不需要這種寫法。
參數綁定說明:
@RequestParam("id")
http://localhost/bbtForum.do?method=listBoardTopic&id=1&userId=10&userName=tom
listBoardTopic(@RequestParam("id")inttopicId,User user)中的topicId綁定到id這個 URL參數,那麼可以通過對入參使用@RequestParam註解來達到目的
@RequestParam(required=false):參數不是必須的,默認爲true
@RequestParam(value="id",required=false)
請求處理方法入參的可選類型
? Java基本數據類型和String
默認情況下將按名稱匹配的方式綁定到URL參數上,可以通過@RequestParam註解改變默認的綁定規則
----------------------------------------------------------------------------------------------------------------------
2.9 @Scope
例如:
說明:
在使用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中有效)
----------------------------------------------------------------------------------------------------------------------
2.10 @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"})
實例:
----------------------------------------------------------------------------------------------------------------------
2.11 @ModelAttribute
這個註解可以跟@SessionAttributes配合在一起用。可以將ModelMap中屬性的值通過該註解自動賦給指定變量。
示例代碼如下:
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
@Controller
@RequestMapping("/user.do")
@SessionAttributes({"u","a"})
public class UserController {
@RequestMapping(params="method=reg4")
public String reg4(ModelMap map) {
System.out.println("HelloController.handleRequest()");
map.addAttribute("u","kobe");
return "index";
}
@RequestMapping(params="method=reg5")
//將屬性u的值賦給形參uname
public String reg5(@ModelAttribute("u")String uname,ModelMap map) {
System.out.println("HelloController.handleRequest()");
System.out.println(uname);
return "index";
}
}
----------------------------------------------------------------------------------------------------------------------
2.12 @InitBinder
說明:
如果希望某個屬性編輯器僅作用於特定的 Controller,可以在 Controller中定義一個標註 @InitBinder註解的方法,可以在該方法中向 Controller了註冊若干個屬性編輯器
例如:
----------------------------------------------------------------------------------------------------------------------
2.13 @Required
例如:
說明:
@ required負責檢查一個bean在初始化時其聲明的 set方法是否被執行,當某個被標註了 @Required的Setter方法沒有被調用,則 Spring在解析的時候會拋出異常,以提醒開發者對相應屬性進行設置。 @Required註解只能標註在 Setter方法之上。因爲依賴注入的本質是檢查 Setter方法是否被調用了,而不是真的去檢查屬性是否賦值了以及賦了什麼樣的值。如果將該註解標註在非 setXxxx()類型的方法則被忽略。
----------------------------------------------------------------------------------------------------------------------
2.14 @Qualifier
例如:
說明:
使用@Autowired時,如果找到多個同一類型的bean,則會拋異常,此時可以使用@Qualifier("beanName"),明確指定bean的名稱進行注入,此時與 @Resource指定name屬性作用相同。
----------------------------------------------------------------------------------------------------------------------
2.15 @ResponseBody
這個註解可以直接放在方法上,表示返回類型將會直接作爲HTTP響應字節。流輸出(不被放置在Model,也不被攔截爲視圖頁面名稱)。可以用於ajax。
3. 常用點
3.1 Controller類中方法返回值的處理
1. 返回string(建議)
a) 根據返回值找對應的顯示頁面。路徑規則爲:prefix前綴+返回值+suffix後綴組成
b) 代碼如下:
2. 也可以返回ModelMap、ModelAndView、map、List、Set、Object、無返回值。一般建議返回字符串!
3.2 請求轉發和重定向
代碼示例:
訪問reg4方法,既可以看到效果。
3.3 獲得request對象、session對象
普通的Controller類,示例代碼如下: