Spring核心——JSR250與資源控制

JSR-175與元編程

要說明JSR-250先要解釋清楚JSR-175,要解釋清楚JSR就的先了解JCP是什麼。網上資料不少,就不細說了,簡單的說JCP(Java Community Process)是管理Java生態(包括J2SE、J2EE等等)發展的合做組織。JSR(Java Specification Request)就是組織內的成員針對Java的發展提出的一些需求,經過審覈以後即會融入到新版本的Java功能中成爲Java的一項特性或功能,不一樣的發行版本和虛擬機都會遵照這些約定。java

JSR-175的全文標題是 A Metadata Facility for the Java Programming Language (爲Java語言提供元數據設施)。它明確提出了在Java平臺引入「元編程」(Meta Programming)的思想,要求提供對「元數據」(Meta Data)的支持。這就是咱們如今大量使用的「@」註解(Annotation)功能的最先來源。JSR-175以後的JSR-181(Web服務支持)、JSR-250、JSR-330都是基於「元數據」功能提出的一些更細節的實現。spring

至於「元編程」、「元數據」是什麼這裏就不詳細展開說明了,它的理論很早就提出了,聽說最先是在Lisp這一類函數式編程語言上開始使用的。網上有不少相關的資料,簡單的說它就是「對源碼進行編碼」,好比下面這樣:編程

class MyClass {
	@Autowired
	private Interface support;
}

經過@Autowired這個註解來對support這個域進行編碼就能夠很輕鬆的擴展原先類的功能。框架

JSR-250的Spring實現

JSR-250主要是圍繞着「資源」的使用預約義了一些註解(Annotation),這裏的「資源」能夠理解爲一個Class類的實例、一個JavaBean、或者一個Spring中的Bean。編程語言

JSR-250相關的註解所有在 javax.annotationjavax.annotation.security 包中,分紅2個部分——資源定義和權限控制。它並無提供具體的實現方式,僅僅是提供了指導性的文檔和幾個註解,由具體的框架去實現。函數式編程

javax.annotation 中包含一下幾個註解:函數

  • @Generated:生成資源的註解,經過該項標記產生的實例是一個資源。相似於Spring中的@Bean註解,用於生成一貫資源。
  • @PostConstruct 創造資源以後的回調處理,Spring已經實現了這個註解,見Bean的定義與控制 一文的介紹。
  • @PreDestroy 銷燬資源以前的回調處理,Spring一樣實現了這個註解,見Bean的定義與控制
  • @Resource 標記使用資源的位置,Spring一樣實現了這個註解的功能(後文會詳細介紹)。功能上有些相似於@Autowired、@Inject,可是二者有很多的差異。
  • @Resources 標記使用多項資源的位置,相似於使用@Autowired向一個列表裝載數據。

仔細看JSR-250定義的這些註解就會發現,他們都是關於「資源」的構建、銷燬、使用的。Spring實現了@PostConstruct、@PreDestroy和@Resource。工具

javax.annotation.security 包中有如下內容:網站

  • @DeclareRoles 聲明角色
  • @DenyAll  拒絕全部角色
  • @PermitAll  受權全部懼色
  • @RolesAllowed  角色受權
  • @RunAs 運行模式

security中的內容是在資源建立以後對資源的使用進行管理。和常規的權限控制模型同樣——定義角色(@DeclareRoles )、肯定角色對資源的控制權限(@DenyAll、@PermitAll 、@RolesAllowed )。Spring並無實現這裏的任何一個註解,在這裏就不深刻介紹了。這一塊內容在J2EE的構建中有很多的應用。ui

Spring中的@Resource

在沒有仔細看Spring的官方文檔和JSR-250以前,我一直覺得@Resource這個註解和@Autowired是2個不一樣的功能,更早的時候還覺得是管理什麼Properties資源的,不少網上的內容也寫得比較模糊。雖然@Resource的實現是在 CommonAnnotationBeanPostProcessor 而@Autowired 是在 AutowiredAnnotationBeanPostProcessor,可是實際上二者的功能是重疊的,或者說@Resource的提供的功能是@Autowired的子集。

在Spring中使用@Resource註解時,把Bean理解爲一項資源就很好理解了。下面經過一些簡單的例子來介紹@Resource的使用。

@Resource的功能是告訴IoC容器標記的位置須要什麼樣的「資源」,以下:

class Abc {}
class Xyz {}
class Implement {
	@Resource
	private Abc abc;
	
	private Xyz xyz;

    @Resource
    private ApplicationContext context;

	@Resource(name="b_instance")
	public void setInject(Xyz xyz) {
		this.xyz = xyz;
	}
}
<beans>
    <context:annotation-config/>
    <bean id="abc" class="x.y.Abc" />
    <bean id="xyz_instance" name="inject" class="x.y.Xyz" />
    <bean class="x.y.Implement" />
</beans>

運行後,IoC會向標記了@Resource的位置注入Bean——是否是感受和@Autowired如出一轍?可是須要注意的是雖然二者最後都是注入一個Bean,可是@Resource和@Autowired的處理過程是不同的。@Autowired若是沒有提供任何參數,那麼他優先按照類型注入,若是要對細節進行控制能夠配合Primary和Qualifiers功能,詳見註解自動裝載的介紹。@Resource是按照命名來注入資源的,以上面的代碼爲例子:

  1. 例如在setter方法上定義了name="xyz_instance"參數,那麼會去IoC容器中尋找id、name等於"xyz_instance"的Bean來注入。
  2. 例如在abc這個域(成員變量)上沒有定義name參數,那麼會使用域的名稱(這裏是"abc")去IoC中按id、name尋找Bean來注入。
  3. 若是@Resource定義在方法上,而且沒有指定name參數,那麼他會使用setter的名稱(例子中方法名爲setInject,名稱就是"inject")來尋找並注入數據。
  4. 最後,若是名稱匹配不上,容器會根據標記位置的類型來注入數據,例如例如中的ApplicationContext。

因此@Resource的裝載資源過程是:1)匹配name參數;2)沒有name參數時會根據setter或域的名稱來匹配Bean的名稱;3)仍是匹配不上就根據標記位置的類型來注入數據。

與@Autowired相比主要有如下幾點區別:

  1. 控制粒度沒有@Autowired細,某些參數Spring並無實現功能。可是使用他更符合整個Java生態的規範。
  2. 若是是使用類型依賴注入數據,應優先使用@Autowired,效率會好一些。
  3. @Resource經過名稱注入與@Autowired相比省去了@Qualifiers等內容。
  4. @Resource只能用在域和Setter方法上。

總的來講若是是按照類型注入依賴對象,那麼最終獲得的結果並無任何差別,只是執行過程上有差異。若是按Bean的名稱使用,@Resource比@Autowired便捷一些,可是功能少不少。

我的建議若是開發的是一個面向終端用戶的應用,好比Web應用、網站什麼的,直接用@Autowired就行了。若是製做的是一個給別的開發人員使用的工具,能夠考慮@Resourec,他能獲得更多框架的支持。

@PostConstruct 與@PreDestroy

@PostConstruct 與@PreDestroy也是JSR-250中定義的註解,Spring都實現了他們的功能,使用方法能夠查看 Bean的定義與控制 相關的說明和介紹。

相關文章
相關標籤/搜索