天天看點

Spring常用注解

使用注解來構造IoC容器

用注解來向Spring容器注冊Bean。需要在applicationContext.xml中注冊<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>。

如:在base-package指明一個包

1 <context:component-scan base-package="cn.gacl.java"/>      

表明cn.gacl.java包及其子包中,如果某個類的頭上帶有特定的注解【@Component/@Repository/@Service/@Controller】,就會将這個對象作為Bean注冊進Spring容器。也可以在<context:component-scan base-package=” ”/>中指定多個包,如:

1 <context:component-scan base-package="cn.gacl.dao.impl,cn.gacl.service.impl,cn.gacl.action"/>      

多個包逗号隔開。

1、@Component

@Component

是所有受Spring 管理元件的通用形式,@Component注解可以放在類的頭上,@Component不推薦使用。

PS:@Component 注解一般把普通 POJO 執行個體化到 Spring 容器中,相當于配置檔案中的<bean id="" class=""/>。

之是以不用它來執行個體化Action、Service、DAO 的原因,我猜應該是 @Component 是 @Controller @Service @Repository 的父類(類似)。而用 @Component 不能在語義上很好地表明這個類所處的層級,是以為了代碼的語義化,還是養成良好的使用習慣。控制層的Action用 @Controller,服務層的 Service 用 @Service,DAO層的用 @Repository 

2、@Controller

@Controller對應表現層的Bean,也就是Action,例如:

1 @Controller
2 @Scope("prototype")
3 public class UserAction extends BaseAction<User>{
4 ……
5 }      

使用@Controller注解辨別UserAction之後,就表示要把UserAction交給Spring容器管理,在Spring容器中會存在一個名字為"userAction"的action,這個名字是根據UserAction類名來取的。注意:如果@Controller不指定其value【@Controller】,則預設的bean名字為這個類的類名首字母小寫,如果指定value【@Controller(value="UserAction")】或者【@Controller("UserAction")】,則使用value作為bean的名字。

這裡的UserAction還使用了@Scope注解,@Scope("prototype")表示将Action的範圍聲明為原型,可以利用容器的scope="prototype"來保證每一個請求有一個單獨的Action來處理,避免struts中Action的線程安全問題。spring 預設scope 是單例模式(scope="singleton"),這樣隻會建立一個Action對象,每次通路都是同一Action對象,資料不安全,struts2 是要求每次次通路都對應不同的Action,scope="prototype" 可以保證當有請求的時候都建立一個Action對象

3、@ Service 

@Service對應的是業務層Bean,例如:

1 @Service("userService")
2 public class UserServiceImpl implements UserService {
3 ………
4 }      

@Service("userService")注解是告訴Spring,當Spring要建立UserServiceImpl的的執行個體時,bean的名字必須叫做"userService",這樣當Action需要使用UserServiceImpl的的執行個體時,就可以由Spring建立好的"userService",然後注入給Action:在Action隻需要聲明一個名字叫“userService”的變量來接收由Spring注入的"userService"即可,具體代碼如下:

1 // 注入userService
2 @Resource(name = "userService")
3 private UserService userService;      

注意:在Action聲明的“userService”變量的類型必須是“UserServiceImpl”或者是其父類“UserService”,否則由于類型不一緻而無法注入,由于Action中的聲明的“userService”變量使用了@Resource注解去标注,并且指明了其name = "userService",這就等于告訴Spring,說我Action要執行個體化一個“userService”,你Spring快點幫我執行個體化好,然後給我,當Spring看到userService變量上的@Resource的注解時,根據其指明的name屬性可以知道,Action中需要用到一個UserServiceImpl的執行個體,此時Spring就會把自己建立好的名字叫做"userService"的UserServiceImpl的執行個體注入給Action中的“userService”變量,幫助Action完成userService的執行個體化,這樣在Action中就不用通過“UserService userService = new UserServiceImpl();”這種最原始的方式去執行個體化userService了。如果沒有Spring,那麼當Action需要使用UserServiceImpl時,必須通過“UserService userService = new UserServiceImpl();”主動去建立執行個體對象,但使用了Spring之後,Action要使用UserServiceImpl時,就不用主動去建立UserServiceImpl的執行個體了,建立UserServiceImpl執行個體已經交給Spring來做了,Spring把建立好的UserServiceImpl執行個體給Action,Action拿到就可以直接用了。Action由原來的主動建立UserServiceImpl執行個體後就可以馬上使用,變成了被動等待由Spring建立好UserServiceImpl執行個體之後再注入給Action,Action才能夠使用。這說明Action對“UserServiceImpl”類的“控制權”已經被“反轉”了,原來主動權在自己手上,自己要使用“UserServiceImpl”類的執行個體,自己主動去new一個出來馬上就可以使用了,但現在自己不能主動去new“UserServiceImpl”類的執行個體,new“UserServiceImpl”類的執行個體的權力已經被Spring拿走了,隻有Spring才能夠new“UserServiceImpl”類的執行個體,而Action隻能等Spring建立好“UserServiceImpl”類的執行個體後,再“懇求”Spring把建立好的“UserServiceImpl”類的執行個體給他,這樣他才能夠使用“UserServiceImpl”,這就是Spring核心思想“控制反轉”,也叫“依賴注入”,“依賴注入”也很好了解,Action需要使用UserServiceImpl幹活,那麼就是對UserServiceImpl産生了依賴,Spring把Acion需要依賴的UserServiceImpl注入(也就是“給”)給Action,這就是所謂的“依賴注入”。對Action而言,Action依賴什麼東西,就請求Spring注入給他,對Spring而言,Action需要什麼,Spring就主動注入給他。

4、@ Repository

@Repository對應資料通路層Bean ,例如: 

1 @Repository(value="userDao")
2 public class UserDaoImpl extends BaseDaoImpl<User> {
3 ………
4 }      

@Repository(value="userDao")注解是告訴Spring,讓Spring建立一個名字叫“userDao”的UserDaoImpl執行個體。

當Service需要使用Spring建立的名字叫“userDao”的UserDaoImpl執行個體時,就可以使用@Resource(name = "userDao")注解告訴Spring,Spring把建立好的userDao注入給Service即可。

1 // 注入userDao,從資料庫中根據使用者Id取出指定使用者時需要用到
2 @Resource(name = "userDao")
3 private BaseDao<User> userDao;      

5、@Resource、@AutoWired、@Qualifier

@Resource、@AutoWired、@Qualifier 都用來注入對象。其中@Resource可以以 name 或 type 方式注入,@AutoWired隻能以 type 方式注入,@Qualifier 隻能以 name 方式注入。

但它們有一些細微差別:

1、@Resource、@Qualifier預設按 byName自動注入,@Autowired預設按byType自動注入。

2、@Resource有兩個屬性是比較重要的,分是name和type。如果使用name屬性,則使用byName的自動注入政策。而使用type屬性時則使用byType自動注入政策。

3、@Resources是JDK提供的注解,而@Autowired是Spring提供的注解。

可以把 @Resource 當成 @AutoWired @Qualifier 的老大吧,哈哈。你們有的,我都有,你們沒有的,我也有~

就用@Resource就好了~

6、@RequestMapping

    @RequestMapping是一種通過比對URL路徑來通路相應頁面的,@RequestMapping 注解将類似 “/user”這樣的URL映射到整個類或特定的處理方法上。一般來說,類級别的注解映射特定的請求路徑到表單控制器上,而方法級别的注解隻是映射為一個特定的HTTP方法請求(“GET”,“POST”等)或HTTP請求參數。

1 @Controller  
2 @RequestMapping("/user")  
3 public class UserController {  
4 @RequestMapping(value = "/list", method = {RequestMethod.GET,RequestMethod.POST})  
5 public String list(HttpServletRequest request) {  
6   
7 }  
8 }      

7、@RestController

@Controller和@RestController的差別?

官方文檔:

@RestController is a stereotype annotation that combines @ResponseBody and @Controller.

意思是:

@RestController注解相當于@ResponseBody + @Controller合在一起的作用。

1)如果隻是使用@RestController注解Controller,則Controller中的方法無法傳回jsp頁面,配置的視圖解析器InternalResourceViewResolver不起作用,傳回的内容就是Return 裡的内容。

    例如:本來應該到success.jsp頁面的,則其顯示success.

2)如果需要傳回到指定頁面,則需要用 @Controller配合視圖解析器InternalResourceViewResolver才行。

3)如果需要傳回JSON,XML或自定義mediaType内容到頁面,則需要在對應的方法上加上@ResponseBody注解。