天天看點

【分享】Spring2.5 注解介紹(3.0通用)

注解說明

• 注冊注解處理器

• 方式一:bean

<bean class="org.springframework.beans.factory.annotation.

AutowiredAnnotationBeanPostProcessor"/>

• 方式二: 命名空間<context:annotation-config />

<context:annotationconfig /> 将隐式地向Spring 容器注冊AutowiredAnnotationBeanPostProcessor 、CommonAnnotationBeanPostProcessor 、 PersistenceAnnotationBeanPostProcessor 以及RequiredAnnotationBeanPostProcessor 這4 個BeanPostProcessor 。

• 方式三: 命名空間<context:component-scan />

如果要使注解工作,則必須配置component-scan ,實際上不需要再配置annotation-config。

base-package 屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會被處理。還允許定義過濾器将基包下的某些類納入或排除。

• Spring 支援以下4 種類型的過濾方式:

• 注解 org.example.SomeAnnotation 将所有使用SomeAnnotation 注解的類過濾出來

• 類名指定 org.example.SomeClass 過濾指定的類

• 正規表達式 com.kedacom.spring.annotation.web..* 通過正規表達式過濾一些類

• AspectJ 表達式 org.example..*Service+ 通過AspectJ 表達式過濾一些類

• 正規表達式的過濾方式舉例:

<context:component-scanbase-package="com.casheen.spring.annotation">

<context:exclude-filtertype="regex"

expression="com.casheen.spring.annotation.web..*"/>

</context:component-scan>

• 注解的過濾方式舉例:

<context:component-scan base-package="com.netqin" >

<context:include-filter type="annotation"

expression="org.springframework.stereotype.Controller"/>

<context:include-filter type="annotation"

expression="org.springframework.stereotype.Service"/>

<context:include-filter type="annotation"

expression="org.springframework.stereotype.Repository"/>

</context:component-scan>

啟用Spring MVC 注解

• 啟動Spring MVC 的注解功能,完成請求和注解POJO 的映射

• <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

注解介紹

• @Controller

• @Service

• @Autowired

• @RequestMapping

• @RequestParam

• @ModelAttribute

• @Cacheable

• @CacheFlush

• @Resource

• @PostConstruct

• @PreDestroy

• @Repository

• @Component (不推薦使用)

• @Scope

• @SessionAttributes

• @InitBinder

• @Required

• @Qualifier

@Controller

• 例如

@Controller

public class SoftCreateController extends SimpleBaseController {}

• 或者

@Controller("softCreateController")

• 說明

@Controller 負責注冊一個bean 到spring 上下文中,bean 的ID 預設為類名稱開頭字母小寫

@Service

• 例如

@Service

public class SoftCreateServiceImpl implements ISoftCreateService {}

• 或者

@Service("softCreateServiceImpl")

• 說明

@Service 負責注冊一個bean 到spring 上下文中,bean 的ID 預設為類名稱開頭字母小寫

@Autowired

• 例如

@Autowired

private ISoftPMService softPMService;

• 或者

@Autowired(required=false)

private ISoftPMService softPMService = new SoftPMServiceImpl();

• 說明

@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 會自動注入這些實作類的執行個體,不需要額外的操作。

@RequestMapping

• 類

@Controller

@RequestMapping("/bbtForum.do")

public class BbtForumController {

@RequestMapping(params = "method=listBoardTopic")

public String listBoardTopic(int topicId,User user) {}

}

• 方法

@RequestMapping("/softpg/downSoftPg.do")

@RequestMapping(value="/softpg/ajaxLoadSoftId.do",method = POST)

@RequestMapping(value = "/osu/product/detail.do", params = { "modify=false" }, method =POST)

• 說明

@RequestMapping 可以聲明到類或方法上

• 參數綁定說明

如果我們使用以下的 URL 請求:

http://localhost/bbtForum.do?method=listBoardTopic&topicId=1&userId=10&userName=tom

topicId URL 參數将綁定到 topicId 入參上,而 userId 和 userName URL 參數将綁定到 user 對象的 userId 和 userName 屬性中。和 URL 請求中不允許沒有 topicId 參數不同,雖然 User 的 userId 屬性的類型是基本資料類型,但如果 URL 中不存在 userId 參數,Spring 也不會報錯,此時 user.userId 值為 0 。如果 User 對象擁有一個 dept.deptId 的級聯屬性,那麼它将和 dept.deptId URL 參數綁定。

@RequestParam

• 參數綁定說明

@RequestParam("id")

http://localhost/bbtForum.do?method=listBoardTopic&id=1&userId=10&userName=tom

listBoardTopic(@RequestParam("id")int topicId,User user) 中的 topicId 綁定到 id 這個 URL 參數, 那麼可以通過對入參使用 @RequestParam 注解來達到目的

@RequestParam(required=false):參數不是必須的,預設為true

@RequestParam(value="id",required=false)

請求處理方法入參的可選類型

• Java 基本資料類型和 String

預設情況下将按名稱比對的方式綁定到 URL 參數上,可以通過 @RequestParam 注解改變預設的綁定規則

• request/response/session

既可以是 Servlet API 的也可以是 Portlet API 對應的對象,Spring 會将它們綁定到Servlet 和 Portlet 容器的相應對象上

• org.springframework.web.context.request.WebRequest

内部包含了 request 對象

• java.util.Locale

綁定到 request 對應的 Locale 對象上

• java.io.InputStream/java.io.Reader

可以借此通路 request 的内容

• java.io.OutputStream / java.io.Writer

可以借此操作 response 的内容

• 任何标注了 @RequestParam 注解的入參

被标注 @RequestParam 注解的入參将綁定到特定的 request 參數上。

• java.util.Map / org.springframework.ui.ModelMap

它綁定 Spring MVC 架構中每個請求所建立的潛在的模型對象,它們可以被 Web 視圖對象通路(如 JSP )

• 指令/ 表單對象(注:一般稱綁定使用 HTTP GET 發送的 URL 參數的對象為指令對象,而稱綁定使用HTTP POST 發送的 URL 參數的對象為表單對象)

它們的屬性将以名稱比對的規則綁定到 URL 參數上,同時完成類型的轉換。

而類型轉換的規則可以通過 @InitBinder 注解或通過 HandlerAdapter 的配置進行調 整

• org.springframework.validation.Errors / org.springframework.validation.BindingResult

為屬性清單中的指令/ 表單對象的校驗結果,注意檢驗結果參數必須緊跟在指令/ 表單對象的後面

• org.springframework.web.bind.support.SessionStatus

可以通過該類型 status 對象顯式結束表單的處理,這相當于觸發 session 清除其中的通過@SessionAttributes 定義的屬性

請求處理方法傳回值的可選類型

• void

此時邏輯視圖名由請求處理方法對應的 URL 确定,如以下的方法:

@RequestMapping("/welcome.do")

public void welcomeHandler() {}

對應的邏輯視圖名為 “ welcome ”

• String

此時邏輯視圖名為傳回的字元,如以下的方法:

@RequestMapping(method = RequestMethod.GET)

public String setupForm(@RequestParam("ownerId") int ownerId, ModelMap model) {

Owner owner = this.clinic.loadOwner(ownerId);

model.addAttribute(owner);

return "ownerForm";

}

對應的邏輯視圖名為 “ ownerForm ”

• org.springframework.ui.ModelMap

和傳回類型為 void 一樣,邏輯視圖名取決于對應請求的 URL ,如下面的例子:

@RequestMapping("/vets.do")

public ModelMap vetsHandler() {

return new ModelMap(this.clinic.getVets());

}

對應的邏輯視圖名為 “ vets ” ,傳回的 ModelMap 将被作為請求對應的模型對象,可以在 JSP 視圖頁面中通路到。

• ModelAndView

當然還可以是傳統的 ModelAndView 。

@ModelAttribute

• 作用域:request

• 例如

@RequestMapping("/base/userManageCooper/init.do")

public String handleInit(@ModelAttribute("queryBean") ManagedUser sUser,Model model,){

• 或者

@ModelAttribute("coopMap")// 将coopMap 傳回到頁 面

public Map<Long,CooperatorInfo> coopMapItems(){}

• 說明

@ModelAttribute 聲明在屬性上,表示該屬性的value 來源于model 裡"queryBean" ,并被儲存到model 裡@ModelAttribute 聲明在方法上,表示該方法的傳回值被儲存到model 裡

@Cacheable 和@CacheFlush

• @Cacheable :聲明一個方法的傳回值應該被緩 存

例如:@Cacheable(modelId = "testCaching")

• @CacheFlush :聲明一個方法是清空緩存的觸發器

例如:@CacheFlush(modelId = "testCaching")

• 說明

要配合緩存處理器使用,參考: http://hanqunfeng.iteye.com/blog/603719

@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屬性作用相同。

參考資料

• jdk1.5 注解介紹

http://hi.baidu.com/gaoyaodi/blog/item/4cee6cf4706f2dddf3d385cd.html

• spring2.5 注解

http://www.infoq.com/cn/articles/spring-2.5-part-1

http://www.infoq.com/cn/articles/spring-2.5-ii-spring-mvc

• spring3.0 注解

http://tech.ddvip.com/2010-05/1273461026153068.html