1. 程式人生 > >Spring註解@學習筆記

Spring註解@學習筆記

過去,Spring使用的Java Bean物件必須在配置檔案[一般為application.xml] 中進行配置,然後才能使用,但Spring2.5版之後,引入了配置註解功能,操作更簡單,但是不瞭解的就抽象了,所以有必要了解一下一些註解的知識;

一,首選注意,註解,注入需要的JAR包,即用common-annotations.jar 包的支援;

二,要使用註解,注入功能需在Spring配置檔案[一般為application.xml]進行必要的配置才能使用註解,注入功能,例如下面;
參見 http://gtgt1988.iteye.com/blog/1670030

  1. <
    beansxmlns="...">
  2.     <!-- 添加註解驅動 -->
  3.     <context:annotation-config/>
  4.     <!-- 預設掃描的包路徑 -->
  5.     <context:component-scanbase-package="cn.org.xxx"/>
  6.     <!--指定預設掃描的包路徑,同時指定不掃描的包,如預設掃描包下的Service不掃描-->
  7.     <!--  
  8.     <context:component-scanbase-package="xx.xxx.yyy"
    />
  9.     <context:exclude-filtertype="annotation"expression="xx.xxx.yyy.Service"/>
  10.     </context:component-scan>
  11.     -->
  12.     <!-- Spring MVC 必須的配置 -->
  13.     <mvc:annotation-driven/>
  14.     <!-- 配置js,css等靜態檔案直接對映到對應的資料夾,不被DispatcherServlet處理 -->
  15.     <mvc:resourceslocation
    ="/resources/"mapping="/resources/**"/>
  16.     <!-- 定義一些檢視控制器,完成訪問路徑到返回檢視的對映關係 -->
  17.     <mvc:view-controllerpath="/"view-name="forward:/logon"/>
  18.     <mvc:view-controllerpath="/permission/login"view-name="permission/login"/>
  19.     <mvc:view-controllerpath="/permission/logout"view-name="permission/login"/>
  20.     <!-- ...其他Bean的配置... -->
  21. </beans>
其中<context:annotation-config/> 的作用是隱式地向 Spring 容器註冊如下四個Bean,這是註解,注入功能的驅動:
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,
PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor 
具體解釋例如:
.如果想使用@Resource 、@PostConstruct、@PreDestroy等註解就必須宣告CommonAnnotationBeanPostProcessor。  
.如果想使用@PersistenceContext註解,就必須宣告PersistenceAnnotationBeanPostProcessor的Bean。  
.如果你想使用@Autowired註解,那麼就必須事先在 Spring 容器中宣告 AutowiredAnnotationBeanPostProcessor Bean。
傳統宣告方式如下:  
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>   
.如果想使用 @Required的註解,就必須宣告RequiredAnnotationBeanPostProcessor的Bean。同樣,傳統的宣告方式如下:  
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/> 

其中<context:component-scan base-package="xx.xxx.xxxx" /> 的作用是掃描指定的包,即尋找指定包內的類class檔案
類似於Spring配置檔案中Bean的定義,如:<bean id="..." class="..."> ,
也可在該元素其中增加<context:exclude-filter type="annotation" expression="xx.yy"/>指定不掃描的包;

其中<mvc:annotation-driven /> 的作用是自動註冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 這兩個bean, 是spring MVC為@Controllers分發請求所必須的。是一種簡寫形式,完全可以手動配置替代這種簡寫形式,簡寫形式可以讓初學快速應用預設配置方案,並提供了資料繫結支援,@NumberFormatannotation支援,@DateTimeFormat支援,@Valid支援,讀寫XML的支援(JAXB),讀寫JSON的支援(Jackson)。

三,在annotaion配置註解中用@Component來表示一個通用註釋,用於說明一個類是一個spring容器管理的類,也即就是該類已經被拉入到spring框架的管理中了。而@Controller, @Service, @Repository等等是@Component的細化,這三個註解比@Component帶有更多的語義,它們分別對應了控制層、服務層、持久層的類,下面逐步瞭解一下部分註解;

1,@Component
把普通pojo例項化到spring容器中,相當於配置檔案中的<bean id="" class=""/>,即類的宣告;

@Component和<context:annotation-config/>和<context:component-scan base-package="com.xxx"/>
三者配合實現無XML配置,只通過註解配置即可將類放入Spring資源容器中。 

如果用注入方式的話就需要在Spring配置檔案application.xml中引入component的掃描元件, 
<context:annotation-config/>和<context:component-scan base-package="com.xxx">   
其中base-package為需要掃描的包(含所有子包)

2,@Resource 
作用是在Spring容器裡面找相應的資源,資源必須先通過Spring配置檔案application.xml等方式預先載入到Spring框架容器中;
http://www.2cto.com/kf/201206/137806.html

可通過name屬性指定查詢的資源名稱,有時name屬性可省,可註解到field或setter方法上面,例如:

  1. public class UserAction {   
  2.     private UserService userService;   
  3.     @Resource(name="userService")   //或@Resource("userService")  
  4.     public void setUserService(UserService userService){   
  5.         this.userService = userService;   
  6.     }   
  7.     public void addUser(){   
  8.         userService.HelloWorld();   
  9.     }   
  10. }   
3,@Autowired 和 @Resource
兩者都用於注入物件功能,
@Autowired 按 byType 自動注入,@Resource 的作用相當於 @Autowired,但@Resource 預設按 byName 自動注入罷了,
@Resource 有兩個屬性是比較重要的,分別是 name 和 type,Spring 將 @Resource 註釋的 name 屬性解析為 Bean 的名字,
而 type 屬性則解析為 Bean 的型別。所以如果使用 name 屬性,則使用 byName 的自動注入策略,
而使用 type 屬性時則使用 byType 自動注入策略。如果既不指定 name 也不指定 type 屬性,這時將通過反射機制使用 byName 自動注入策略。

Resource 註釋類位於 Spring 釋出包的 lib/j2ee/common-annotations.jar 類包中;

4,@Repository
該註解是用來給持久層的類定義一個名字,讓Spring根據這個名字關聯到這個類。
例如:

  1. @Repository("userDao")   
  2. publicclass UserDaoImpl  implements UserDao{   
  3.    //...
  4. }   
聲明瞭UserDaoImpl ,它在Spring容器中叫userDao這個名字; 另外標籤:@Autowired 用來注入,例如: 
  1. @Autowired
  2. private UserDao userDao;  
這樣就注入到Spring容器中進去了,相當於我們new了這個實現類並且加入到Spring框架的容器中,我們就無需寫setter方法了。 

5,@Controller, 
使用 @Controller 註解定義一個 Controller 控制器。使用@Controller 標記的類就是一個SpringMVC Controller 物件;但還不能使用,需要把控制器類加入到Spring框架容器中才能使用;

  1. @Controller
  2. publicclass MyController {    
  3.     @RequestMapping ( "/showView" )    
  4.     public ModelAndView showView() {    
  5.        ModelAndView modelAndView = new ModelAndView();    
  6.        modelAndView.setViewName( "viewName" );    
  7.        modelAndView.addObject( "需要放到model中的屬性名稱" , "對應的屬性值,它是一個物件");    
  8.        return modelAndView;    
  9.     }      
  10. }   
控制器類加入到Spring框架容器中有兩種方法:
(1)在SpringMVC 的配置檔案[application.xml]中定義MyController的bean物件,如下:
<bean class="com.host.app.web.controller.MyController"/>
(2)在SpringMVC 的配置檔案[application.xml]中告訴Spring 該到哪裡去找標記為@Controller 的Controller控制器。
<context:component-scan base-package = "com.host.app.web.controller" >  
   <context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Service" />  
</context:component-scan >   
注:上面 context:exclude-filter 標註的是不掃描 @Service 標註的類

6,@Service, 
@Service用於標註業務層元件,相當於定義一個bean然後新增到Spring容器中;如:@Service("名稱"),如果未指定名稱則自動根據Java Bean的類名生成一個首字母小寫跟bean類名稱同名的名稱,
  1. //(指定在Spring容器中的名稱),相當於在Spring容器中通過myUserService名稱即可找到UserServiceImpl類的例項
  2. @Service("myUserService")   
  3. publicclass UserServiceImpl implements userService {    
  4.     //...code...
  5. }  
  6. //如果不指定名稱則生成一個跟類名相同,但首字母小寫的該類例項,並加到Spring容器中,即在Spring容器中通過logServiceImpl可找到該類例項
  7. @Service
  8. publicclass LogServiceImpl implements LogService {    
  9.     //...code...
  10. }  
7,@RequestMapping
使用 @RequestMapping 來完成 Request 請求到處理器或處理器方法的對映。
使用@RequestMapping 可把URL對映到控制器類,或者控制器類的某個處理方法上,當@RequestMapping 標記在Controller 類上時,
表明該控制器類所有方法處理的請求都基於前面的URL,控制器類裡面的方法如果再使用@RequestMapping時,請求的路徑是相對於
類上面的請求路徑,也即基於前面的請求路徑;如果控制器類前沒有@RequestMapping 標記時,控制器類裡面方法的@RequestMapping則
相對host根路徑,例如:
  1. @Controller
  2. @RequestMapping ("/user")  //markA
  3. publicclass MyController {    
  4.     @RequestMapping ( "/userInfo" ) //markB
  5.     public ModelAndView showView() {    
  6.        ModelAndView modelAndView = new ModelAndView();    
  7.        modelAndView.setViewName( "viewName" );    
  8.        modelAndView.addObject( "需要放到model中的屬性名稱" , "對應的屬性值,它是一個物件");    
  9.        return modelAndView;    
  10.     }