1. 程式人生 > >Spring MVC 4 常用註解彙總

Spring MVC 4 常用註解彙總

       最近在用Spring boot做REST風格介面的新架構,由於已經快2年沒有大規模使用Spring MVC了,發現很多新的註解都沒有用過,因此花了點時間學習和彙總,Spring MVC現在功能還是很強大的。 通過大量使用註解可以簡化REST介面的開發。

         Spring從2.5版本開始在程式設計中引入註解,使用者可以使用@RequestMapping, @RequestParam, @ModelAttribute等等這樣類似的註解。到目前為止,Spring的版本雖然發生了很大的變化,但註解的特性卻是一直延續下來,並不斷擴充套件,讓廣大的開發人員的雙手變的更輕鬆起來,這都離不開Annotation的強大作用,今天我們就一起來看看Spring MVC 4中常用的那些註解吧。

    1. @Controller

    Controller控制器是通過服務介面定義的提供訪問應用程式的一種行為,它解釋使用者的輸入,將其轉換成一個模型然後將試圖呈獻給使用者。Spring MVC 使用 @Controller 定義控制器,它還允許自動檢測定義在類路徑下的元件並自動註冊。如想自動檢測生效,需在XML標頭檔案下引入 spring-context:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
 
    <context:component-scan base-package="org.springframework.samples.petclinic.web"/>
 
    <!-- ... --></beans>


    2. @RequestMapping

    我們可以 @RequestMapping 註解將類似 “/favsoft”這樣的URL對映到整個類或特定的處理方法上。一般來說,類級別的註解對映特定的請求路徑到表單控制器上,而方法級別的註解只是對映為一個特定的HTTP方法請求(“GET”,“POST”等)或HTTP請求引數。

@Controller
@RequestMapping("/favsoft")
public class AnnotationController {
     
    @RequestMapping(method=RequestMethod.GET)
    public String get(){
        return "";
    }
     
    @RequestMapping(value="/getName", method = RequestMethod.GET)
    public String getName(String userName) {
        return userName;
    }
     
    @RequestMapping(value="/{day}", method=RequestMethod.GET)
    public String getDay(Date day){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        return df.format(day);
    }
     
    @RequestMapping(value="/addUser", method=RequestMethod.GET)
    public String addFavUser(@Validated FavUser favUser,BindingResult result){
        if(result.hasErrors()){
            return "favUser";
        }
        //favUserService.addFavUser(favUser);
        return "redirect:/favlist";
    }
 
    @RequestMapping("/test")
    @ResponseBody
    public String test(){
        return "aa";
    }
     
}

    @RequestMapping 既可以作用在類級別,也可以作用在方法級別。當它定義在類級別時,標明該控制器處理所有的請求都被對映到 /favsoft 路徑下。@RequestMapping中可以使用 method 屬性標記其所接受的方法型別,如果不指定方法型別的話,可以使用 HTTP GET/POST 方法請求資料,但是一旦指定方法型別,就只能使用該型別獲取資料。

    @RequestMapping 可以使用 @Validated與BindingResult聯合驗證輸入的引數,在驗證通過和失敗的情況下,分別返回不同的檢視。

    @RequestMapping支援使用URI模板訪問URL。URI模板像是URL模樣的字串,由一個或多個變數名字組成,當這些變數有值的時候,它就變成了URI。

  3. @PathVariable

    在Spring MVC中,可以使用 @PathVariable 註解方法引數並將其繫結到URI模板變數的值上。如下程式碼所示:

 String findOwner( String , Model model) {
    FavUser favUser = favUserService.findFavUser();
    model.addAttribute(
     ;
}

 URI模板 “favusers/{favUserId}"指定變數的名字 favUserId ,當控制器處理這個請求的時候, favUserId的值會被設定到URI中。比如,當有一個像“favusers/favccxx”這樣的請求時,favUserId的值就是 favccxx。

    @PathVariable 可以有多個註解,像下面這樣:

@RequestMapping(value="/owners/{ownerId}/pets/{petId}", method=RequestMethod.GET)public String findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
    Owner owner = ownerService.findOwner(ownerId);
    Pet pet = owner.getPet(petId);
    model.addAttribute("pet", pet);    return "displayPet";
}

   

    @PathVariable中的引數可以是任意的簡單型別,如int, long, Date等等。Spring會自動將其轉換成合適的型別或者丟擲 TypeMismatchException異常。當然,我們也可以註冊支援額外的資料型別。

    如果@PathVariable使用Map<String, String>型別的引數時, Map會填充到所有的URI模板變數中。

    @PathVariable支援使用正則表示式,這就決定了它的超強大屬性,它能在路徑模板中使用佔位符,可以設定特定的字首匹配,字尾匹配等自定義格式。 

    @PathVariable還支援矩陣變數,因為現實場景中用的不多,這就不詳細介紹了,有需要的童鞋請檢視官網的文件。

    4. @RequestParam

    @RequestParam將請求的引數繫結到方法中的引數上,如下面的程式碼所示。其實,即使不配置該引數,註解也會預設使用該引數。如果想自定義指定引數的話,如果將@RequestParam的 required 屬性設定為false(如@RequestParam(value="id",required=false))。

    5. @RequestBody

    @RequestBody是指方法引數應該被繫結到HTTP請求Body上。

@RequestMapping(value = "/something", method = RequestMethod.PUT)public void handle(@RequestBody String body, Writer writer) throws IOException {
    writer.write(body);
}

   如果覺得@RequestBody不如@RequestParam趁手,我們可以使用 HttpMessageConverter將request的body轉移到方法引數上, HttMessageConverser將 HTTP請求訊息在Object物件之間互相轉換,但一般情況下不會這麼做。事實證明,@RequestBody在構建REST架構時,比@RequestParam有著更大的優勢。

  6. @ResponseBody

    @ResponseBody與@RequestBody類似,它的作用是將返回型別直接輸入到HTTP response body中。@ResponseBody在輸出JSON格式的資料時,會經常用到,程式碼見下圖:

@RequestMapping(value = "/something", method = RequestMethod.PUT)@ResponseBodypublic String helloWorld() {    return "Hello World";
}

    7. @RestController

    我們經常見到一些控制器實現了REST的API,只為服務於JSON,XML或其它自定義的型別內容,@RestController用來建立REST型別的控制器,與@Controller型別。@RestController就是這樣一種型別,它避免了你重複的寫@RequestMapping與@ResponseBody。

@RestController
public class FavRestfulController {
 
@RequestMapping(value="/getUserName",method=RequestMethod.POST)
public String getUserName(@RequestParam(value="name") String name){
   return name;
}
}


    8. HttpEntity

    HttpEntity除了能獲得request請求和response響應之外,它還能訪問請求和響應頭,如下所示:

@RequestMapping("/something")public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws UnsupportedEncodingException {
    String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader"));    byte[] requestBody = requestEntity.getBody();    // do something with request header and body

    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.set("MyResponseHeader", "MyValue");    return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}

 

    9. @ModelAttribute

    @ModelAttribute可以作用在方法或方法引數上,當它作用在方法上時,標明該方法的目的是新增一個或多個模型屬性(model attributes)。該方法支援與@RequestMapping一樣的引數型別,但並不能直接對映成請求。控制器中的@ModelAttribute方法會在@RequestMapping方法呼叫之前而呼叫,示例如下:

@ModelAttribute
public Account addAccount(@RequestParam String number) {
    return accountManager.findAccount(number);
}

@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
    model.addAttribute(accountManager.findAccount(number));    
    // add more ...
}

 

    @ModelAttribute方法用來在model中填充屬性,如填充下拉列表、寵物型別或檢索一個命令物件比如賬戶(用來在HTML表單上呈現資料)。

    @ModelAttribute方法有兩種風格:一種是新增隱形屬性並返回它。另一種是該方法接受一個模型並新增任意數量的模型屬性。使用者可以根據自己的需要選擇對應的風格。

    @ModelAttribute作用在方法引數上

    當@ModelAttribute作用在方法引數上時,表明該引數可以在方法模型中檢索到。如果該引數不在當前模型中,該引數先被例項化然後新增到模型中。一旦模型中有了該引數,該引數的欄位應該填充所有請求引數匹配的名稱中。這是Spring MVC中重要的資料繫結機制,它省去了單獨解析每個表單欄位的時間。

    @ModelAttribute是一種很常見的從資料庫中檢索屬性的方法,它通過@SessionAttributes使用request請求儲存。在一些情況下,可以很方便的通過URI模板變數和型別轉換器檢索屬性。

@Cacheable 和@CacheFlush

              • @Cacheable :宣告一個方法的返回值應該被快取。例如:@Cacheable(modelId = "testCaching")

              • @CacheFlush :宣告一個方法是清空快取的觸發器。例如:@CacheFlush(modelId = "testCaching")

              • 說明

     spring3.0沒有對快取提供支援,不過3.1之後就有了,可以參考:Spring3.1 Cache註解

@Resource

      • 例如

              @Resource
              private DataSource dataSource; // inject the bean named 'dataSource'

      • 或者

    @Resource(name="dataSource")
    @Resource(type=DataSource.class)

  • 說明

  @Resource 預設按bean 的name 進行查詢,如果沒有找到會按type 進行查詢,
  此時與@Autowired 類 似

  在沒有為 @Resource 註解顯式指定 name 屬性的前提下,如果將其標註在 BeanFactory 型別、ApplicationContext 型別、ResourceLoader 型別、  ApplicationEventPublisher 型別、MessageSource 型別上,那麼 Spring 會自動注入這些實現類的例項,不需要額外的操作。此時 name 屬性不需要指定 ( 或者指定為""),否則注入失敗;

@PostConstruct 和@PreDestroy

  • @PostConstruct

在方法上加上註解@PostConstruct ,這個方法就會在Bean 初始化之後被Spring 容器執 行
(注:Bean 初始化包括,例項化Bean ,並裝配Bean 的屬性(依賴注入))。

  • @PreDestroy
在方法上加上註解@PreDestroy ,這個方法就會在Bean 被銷燬前被Spring 容器執行。

@Repository

• 與@Controller 、@Service 類似,都是向spring 上下文中註冊bean ,不在贅述。

@Component (不推薦使用)

  • @Component

@Component 是所有受Spring 管理元件的通用形式,Spring 還提供了更加細化的註解形式:  @Repository 、@Service、@Controller ,它們分別對應儲存層Bean ,業務層Bean ,和展示層Bean 。

目前版本(2.5 )中,這些註解與@Component 的語義是一樣的,完全通用, 在Spring 以後的版本中可能會給它們追加更多的語義。 所以,我們推薦使用@Repository 、@Service 、@Controller 來替代@Component 。

@Scope

       • 例如

             @Scope("session")

             @Repository()

              public class UserSessionBean implementsSerializable {}

       • 說明

    在使用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中有效)

@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"})

@InitBinder

  • 說明

  如果希望某個屬性編輯器僅作用於特定的 Controller ,
  可以在 Controller 中定義一個標註 @InitBinder 註解的方法,
  可以在該方法中向 Controller 了註冊若干個屬性編輯器

  • 例如

  @InitBinder
  public void initBinder(WebDataBinder binder) {

  SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
  dateFormat.setLenient(false);
  binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));

}

@Required

      • 例如

             @required              

              public  setName(String name){} 

       • 說明

              @ required 負責檢查一個bean在初始化時其宣告的 set方法是否被執行, 當某個被標註了 @Required 的 Setter 方法沒有被呼叫,則 Spring 在解析的時候會丟擲異常,以提醒開發者對相應屬性進行設定。 @Required 註解只能標註在 Setter 方法之上。因為依賴注入的本質是檢查 Setter 方法是否被呼叫了,而不是真的去檢查屬性是否賦值了以及賦了什麼樣的值。如果將該註解標註在非 setXxxx() 型別的方法則被忽略。

@Qualifier

       • 例如

              @Autowired

              @Qualifier("softService")
              private ISoftPMService softPMService;

       • 說明

            使用@Autowired 時,如果找到多個同一型別的bean,則會拋異常,此時可以使用 @Qualifier("beanName"),明確指定bean的名稱進行注入,此時與 @Resource指定name屬性作用相同。


spring4中提供了大量的註解來支援零配置

@Configuration : 類似於spring配置檔案,負責註冊bean,對應的提供了@Bean註解。需要org.springframework.web.context.support.AnnotationConfigWebApplicationContext註冊到容器中。

@ComponentScan : 註解類查詢規則定義 <context:component-scan/>

@EnableAspectJAutoProxy : 啟用Aspect自動代理 <aop:aspectj-autoproxy/>

@Import @ImportResource: 關聯其它spring配置  <import resource="" />

@EnableCaching :啟用快取註解  <cache:annotation-driven/>

@EnableTransactionManagement : 啟用註解式事務管理 <tx:annotation-driven />

@EnableWebMvcSecurity : 啟用springSecurity安全驗證

最後放上網友整理的spring註解圖

    2.1 spring-context模組的註解圖

 2.2 spring-web註解

2.3 spring其它模組的註解

3