因為要看Spring中註解的具體定義,所以在說之前,先來簡單說下JAVA中註解的一些基本知識。
元註解
什麼是元註解呢,就是註解的註解。java中提供了以下幾種:
-
@Target
註解的作用域描述
public enum ElementType { /** 類, 介面 或者列舉 */ TYPE, /** 欄位 */ FIELD, /** 方法 */ METHOD, /** 引數 */ PARAMETER, /** 構造方法 */ CONSTRUCTOR, /** 區域性變數 */ LOCAL_VARIABLE, /** 註解型別 */ ANNOTATION_TYPE, /** 包 */ PACKAGE } 複製程式碼
-
@Retention
生命週期描述
public enum RetentionPolicy { /** * 在原檔案中有效,被編譯器丟棄。 */ SOURCE, /** * 在class檔案有效,可能會被虛擬機器忽略。 */ CLASS, /** * 在執行時有效。 */ RUNTIME } 複製程式碼
-
@Inherited
標識性的元註解,它允許子註解繼承它。
-
@Documented
用於標準生成javadoc時會包含的註解。
JAVA中註解的定義方式
public @interface 註解名 {定義體}
複製程式碼
上面試一些基本概念點,關注註解其他的一些特性和用法就不細說了。直接看Spring中的註解吧。
1、@Component
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
*/
String value() default "";
}
複製程式碼
指示註釋類是“元件”。 當使用基於註釋的配置和類路徑掃描時,這些類被認為是自動檢測的候選物件。
2、@Controller
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
String value() default "";
}
複製程式碼
使用過Spring mvc的小夥伴對於這個註解肯定不陌生。@Controller表示註釋的類是“控制器”(例如Web控制器)。這個註解作為@Component的一個特定方式存在,允許通過類路徑掃描來自動檢測實現類。通常情況下會結合RequestMapping註解使用。從它的定義層面來看,這個註解只能用於介面或者類上面,不能用於方法或者屬性欄位上面。
3、@Service
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
String value() default "";
}
複製程式碼
表示註釋類是一個“服務”,最初由Domain-Driven Design (Evans,2003)定義為“作為模型中獨立的介面提供的操作,沒有封裝狀態”。
在一般情況下,我們把他用在標準我們的service服務介面的實現類上面,實際上這相當於縮小它們的語義和適當的使用。
@Service這個註釋作為 @Component的一個特例,允許通過類路徑掃描來自動檢測實現類。
4、@Repository
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any
*/
String value() default "";
}
複製程式碼
用於標註資料訪問元件,即DAO元件
5、@RequestMapping
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
複製程式碼
@RequestMapping是一個用來處理地址對映請求的註解,從定義可以看出,可作用於方法或者類上。
- 用於類上,大多數是為了進行區分controller
- 用於方法上則是對方法進行註解以產生訪問的路徑。
它包括了幾個屬性:
- value 用於設定方法或者類的對映路徑,可以直接寫路徑。我們通常都是直接寫,例如:@RequestMapping("/XXX");
- method 用於指定請求的方法,可以設定單個或多個,如果請求方法不滿足條件則會請求失敗。
- params 指定request中必須包含某些引數值是,才讓該方法處理。
- name 此對映指定一個名稱
- path 僅在Servlet環境中:路徑對映URI(例如“/myPath.do”)。也支援Ant風格的路徑模式(例如“/myPath/*.do”)。在方法級別,在型別級別表示的主對映內支援相對路徑(例如“edit.do”)。 路徑對映URI可能包含佔位符(例如“/ $ {connect}”)
- consumes 指定處理請求的提交內容型別(Content-Type),例如application/json, text/html;
- produces 指定返回的內容型別,僅當request請求頭中的(Accept)型別中包含該指定型別才返回;
- headers 指定request中必須包含某些指定的header值,才能讓該方法處理請求。
其他的幾個沒怎麼用過,確實不瞭解,有知道的小夥伴,歡迎留言。
6、@ResponseBody
@ResponseBody這個我一般是用在做非同步請求呼叫的方法上來使用的。因為在使用@RequestMapping後,返回值通常解析為跳轉路徑。加上@responsebody後,返回結果直接寫入HTTP response body中,不會被解析為跳轉路徑。
對於非同步請求,我們不希望返回解析檢視,二是希望響應的結果是json資料,那麼加上@responsebody後,就會直接返回json資料。
7、@Autowired
Autowired就是自動裝配的意思,其作用是為了消除程式碼Java程式碼裡面的getter/setter與bean屬性中的property。當然,getter看個人需求,如果私有屬性需要對外提供的話,就應該保留。
@Autowired預設按型別匹配的方式,在容器查詢匹配的Bean,當有且僅有一個匹配的Bean時,Spring將其注入@Autowired標註的變數中。
但是當介面存在兩個實現類的時候必須使用@Qualifier指定注入哪個實現類,否則可以省略,只寫@Autowired。
8、@Qualifier
@Qualifier用於指定注入Bean的名稱,就是上面說到的,如果容器中有一個以上匹配的Bean,則可以通過@Qualifier註解限定Bean的名稱。
9、@Resource
這個註解不是Spring的,放在這裡是為了和@Autowired做一個區別。 @Resource預設按名稱裝配,當找不到與名稱匹配的bean才會按型別裝配。
10、@PathVariable
當使用@RequestMapping URI template 樣式對映時, 即 someUrl/{paramId}, 這時的paramId可通過 @Pathvariable註解繫結它傳過來的值到方法的引數上。
@RequestMapping("/user/{userId}")
public ModelAndView userCenter(HttpServletRequest request,
HttpServletResponse response,
@PathVariable String userId){
//do something
}
複製程式碼
如果方法引數名稱和需要繫結的uri template中變數名稱不一致,需要在@PathVariable("name")指定uri template中的名稱。
11、@RequestParam
@RequestParam註解有兩個屬性: value、required;
- value用來指定要傳入值的id名稱
- required用來指示引數是否必須繫結;
舉個例子:
@RequestMapping("/t_rparam1")
public String t_rparam1(@RequestParam Long userId) {
//do something
}
@RequestMapping("/t_rparam2")
public String t_rparam2(Long userId) {
//do something
}
複製程式碼
- t_rparam1 必須帶有引數,也就是說你直接輸入localhost:8080/t_rparam1 會報錯只能輸入localhost:8080/t_rparam1?userId=? 才能執行相應的方法
- t_rparam2 可帶引數也可不帶引數;也就是說輸入localhost:8080/t_rparam2和輸入 localhost:8080/t_rparam2?userId=?都可以正常執行
當然我們也可以設定 @RequestParam 裡面的required為false(預設為true 代表必須帶引數) 這樣t_rparam1就跟t_rparam2是一樣的了。
12、@RequestHeader
利用@RequestHeader 註解可以把Request請求header部分的值繫結到方法的引數上。
@RequestMapping("/t_heander")
public void getRequestHeaderTest(HttpServletRequest request,
HttpServletResponse response,
@RequestHeader("Accept-Encoding")String encoding) {
//do something
}
複製程式碼
13、@CookieValue
@CookieValue就是把Request header中cookie的值繫結到方法的引數上。比如說我們的cookie如下:
Cookie:JSESSIONID=ka8A5L5t7WTUPXbaLupBieqOdmc0ZpD5MyKvea6oQr7JJSIZzM;userId=001;sysFlag=glmapper
複製程式碼
獲取如下:
@RequestMapping("/t_cookie")
public void getCookieValueTest(@CookieValue("JSESSIONID") String cookie) {
//do something
}
複製程式碼
14、@RequestBody
@RequestBody這個註解常用來處理Content-Type不是application/x-www-form-urlencoded編碼的內容,比如說:application/json, application/xml等等;這個和ResonseBody可以反過來理解。
15、@ModelAttribute
-
方法上
通常用來在處理@RequestMapping之前,為請求繫結需要從後臺查詢的model;
-
引數上
用來通過名稱對應,把相應名稱的值繫結到註解的引數bean上;
參考
- 《Spring技術內幕》
- https://www.cnblogs.com/FrankLei/p/6579843.html