国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于Resin的通用依賴注入模式

2016-09-18 06:29:37劉小可河南省科學(xué)技術(shù)信息研究院河南鄭州450003
河南科技 2016年10期
關(guān)鍵詞:例子形容詞應(yīng)用程序

劉小可(河南省科學(xué)技術(shù)信息研究院,河南 鄭州 450003)

基于Resin的通用依賴注入模式

劉小可
(河南省科學(xué)技術(shù)信息研究院,河南鄭州450003)

本文描述四種CanDI設(shè)計(jì)模式:服務(wù),資源,啟動(dòng)和擴(kuò)展模式,以服務(wù)模式為基礎(chǔ)的應(yīng)用程序采用封裝方式管理數(shù)據(jù),資源模式是用戶和應(yīng)用程序之間的配置接口,啟動(dòng)模式用于初始化應(yīng)用,擴(kuò)展模式用于用戶定制復(fù)雜的應(yīng)用程序行為。

CanDI依賴注入;注解;模式

1 概述

CanDI作為Caucho公司對(duì)下一代通用依賴注入技術(shù)標(biāo)準(zhǔn)的CDI獨(dú)立實(shí)現(xiàn),主要包含四種Java注入模式,其設(shè)計(jì)目標(biāo)在于采用聲明式注入方式改善Java類代碼,使之展現(xiàn)出更加清晰的依賴關(guān)系,生命周期,輸出,定義等。工程師可以在讀取類的同時(shí)了解它們的表現(xiàn)方式,無(wú)需讀取XML的配置文件,即可知道系統(tǒng)程序的行為是什么。

類型安全的自定義注解綁定是CanDI實(shí)現(xiàn)的技術(shù)關(guān)鍵,在注入點(diǎn)可以利用生動(dòng)的注解名稱對(duì)資源或者服務(wù)進(jìn)行清晰描述。注解本身就是Java的真實(shí)類,它們?cè)贘avaDoc中定義并由編譯器負(fù)責(zé)解釋。少量生動(dòng)的注解可以減少代碼編寫負(fù)擔(dān),并節(jié)省開發(fā)時(shí)間。

表1 基于CanDI的應(yīng)用模式

服務(wù)模式主要是為滿足封裝多客戶端的狀態(tài)和管理需要,本文展示一個(gè)用于多Servlet、PHP和JSP腳本的單服務(wù)例子。采用服務(wù)模式的應(yīng)用通常使用@Inject注解并綁定為單例模式。

資源模式主要通過XML文件為資源配置驅(qū)動(dòng)類和屬性,這部分內(nèi)容使用MyResource作為一個(gè)通用資源API,我們可以把它當(dāng)作是某個(gè)DataSource或者Entity-Manager,應(yīng)用程序主要需要綁定@Red和@Blue。資源API是通用的,我們需要在具體應(yīng)用程序的代碼中定義描述其意圖。綁定注解所用的詞匯一般是簡(jiǎn)單、清晰、易于理解的形容詞,并且數(shù)量較少。作為BlueResourceBean這樣的驅(qū)動(dòng)類就可以在XML文件中進(jìn)行配置,同樣如果需要配置數(shù)據(jù)庫(kù)也是這么做。

許多應(yīng)用需要啟動(dòng)模式的初始化功能,我們可以使用CanDI提供的啟動(dòng)模式定義啟動(dòng)類,并且不需要額外的XML配置,這是因?yàn)镃anDI可以在classpath中自動(dòng)尋找Bean,我們可以使用@Startup注解和@PostConstruct方法來(lái)對(duì)要?jiǎng)?chuàng)建的啟動(dòng)Bean進(jìn)行標(biāo)識(shí)。

擴(kuò)展服務(wù)主要用于系統(tǒng)內(nèi)部使用,它可以提升許多應(yīng)用的靈活性。擴(kuò)展模式不需要使用其他配置,只需要使用CanDI型的插件即可完成查找裝配。本文使用MyResource API作為插件,捕捉所有使用CanDI Instance接口的實(shí)現(xiàn)和@Any注解類。

2 Java注入API

許多應(yīng)用主要使用服務(wù)和資源模式,CanDI類中最重要的三個(gè)注解就是@Inject、@Qualifier和@Singleton,通過有效使用這三種注解,可以提升應(yīng)用中服務(wù)和資源的可讀性、可維護(hù)性,如表2所示。

表2 服務(wù)和資源模式中主要的CanDI類

提供腳本方式訪問服務(wù)和資源的應(yīng)用可以使用@Named注解進(jìn)行聲明,這樣在腳本可以直接使用其對(duì)應(yīng)的名字來(lái)進(jìn)行操作,如表3所示。

表3 CanDI的腳本支持類

啟動(dòng)模式使用兩個(gè)注解:@Startup注解用于標(biāo)記容器啟動(dòng)時(shí)需要?jiǎng)?chuàng)建的Bean,@PostConstruct注解用于需要初始化的方法,如表4所示。

表4 啟動(dòng)模式的CanDI類

擴(kuò)展模式使用兩個(gè)CanDI類使其易于通過classpath查找插件。Instance提供了查找到的Bean的枚舉,@Any注解選定所有依賴@Qualifier注解的Bean,如表5所示。

表5 擴(kuò)展模式的CanDI類

程序例子架構(gòu):見圖1。

圖1 程序例子的技術(shù)架構(gòu)

涉及的程序文件

服務(wù)模式:見表6。

配置和擴(kuò)展模式:見表7。

啟動(dòng)模式:見表8。

3 服務(wù)模式

由于應(yīng)用的服務(wù)通常是特定的,一般服務(wù)接口設(shè)計(jì)做成獨(dú)立的服務(wù)。在CanDI中,@Inject注解向客戶端類注入特定的服務(wù)。服務(wù)的聲明和使用都使用聲明方式將服務(wù)限定在@Singleton范圍,同時(shí)在客戶端使用@Inject注解將服務(wù)注入。CanDI的服務(wù)注解類自身通過這種描述方式提升可讀性和靈活性。

例子:GetServlet.java

package example;

import javax.inject.Inject;

...

public class GetServlet extends HttpServlet{

private@Inject MyService_service;

...

用戶可以通過類似于MyService這樣的接口訪問服務(wù)。服務(wù)接口的實(shí)現(xiàn)是類似于MyServiceBean的具體類。CanDI的接口API屬于Java標(biāo)準(zhǔn)接口,因此不依賴于具體的CanDI注解或者引用。

例子:MyService.java

package example;

public interface MyService{

public void setMessage(String message);

public String getMessage();

表6 服務(wù)模式涉及的程序文件表

表7 配置和擴(kuò)展模式涉及的程序文件

表8 啟動(dòng)模式涉及的程序文件

所有與類部署有關(guān)的信息都包含在類本身,原因在于CanDI通過classpath查找發(fā)現(xiàn)服務(wù)的具體實(shí)現(xiàn)類。換句話說,服務(wù)的部署來(lái)自于自身定義。服務(wù)做成單例時(shí),則被@Singleton注解限定。其他注解是可選的,主要用于描述服務(wù)的注冊(cè)或者行為。例如,本文使用@Named注解標(biāo)簽,這是因?yàn)閠est.jsp和test.php中用到了名字引用。

為了集成JSP的EL表達(dá)式語(yǔ)言和PHP編程的需要,腳本Bean需要使用CanDI Bean中的@Named注解。由于CanDI使用服務(wù)類型和綁定注解的方式進(jìn)行匹配,因此非腳本Bean不需要聲明@Named。

例子:MyServiceBean.java

package example;

import javax.inject.Singleton;

import javax.inject.Named;

import javax.enterprise.inject.Default;

@Singleton

@Named("myService")

@Default

public class MyServiceBean implements MyService{

private String_message="default";

public void setMessage(String message){

_message=message;

public String getMessage(){

return_message;

在PHP和JSP中使用服務(wù)

CanDI的設(shè)計(jì)與PHP和JSP等腳本語(yǔ)言緊密結(jié)合。腳本語(yǔ)言可以使用名字字符串加載CanDI服務(wù)和資源,腳本語(yǔ)言不具備依賴注入的強(qiáng)類型要求,由此,CanDI服務(wù)中由@Named注解聲明的名字字符串就是Bean自身。PHP和JSP代碼通過Bean的名字完成對(duì)其引用,在PHP中,可以使用java_bean函數(shù)調(diào)用對(duì)應(yīng)的類:

例子:test.php

<?php

$myService=java_bean("myService");

echo$myService->getMessage();

?>

PHP使用函數(shù)訪問CanDI服務(wù)和資源,JSP和JSF通過JSP表達(dá)式語(yǔ)言訪問CanDI的Bean。EL表達(dá)式可以使用任何帶有@Named注解的CanDI Bean:

例子:test.jsp

message:${myService.message}

4 XML資源配置模式

像數(shù)據(jù)庫(kù)、應(yīng)用程序中的多角色隊(duì)列在生成Data-Source和BlockingQueue時(shí)需要對(duì)這些資源進(jìn)行描述配置。當(dāng)需要生成特定的或可以使用@Inject注解的服務(wù)時(shí),通常創(chuàng)建個(gè)性化的@Qualifier注解以定義和驗(yàn)證資源。

CanDI鼓勵(lì)以綁定注解的方式使用少量形容詞描述資源,典型的中等應(yīng)用像郵件列表管理或許一半都需要個(gè)性化綁定的形容詞,多與少依賴于特定資源的數(shù)量。每一個(gè)數(shù)據(jù)庫(kù)、隊(duì)列、郵件和JPA實(shí)體管理器會(huì)生成對(duì)應(yīng)的特定名字。如果用戶需要個(gè)性化配置內(nèi)部資源,那么需要附加綁定類型。如果應(yīng)用系統(tǒng)是單數(shù)據(jù)庫(kù),只需要一個(gè)綁定注解即可,或者只使用@Inject。

綁定注解的目的是在客戶端代碼中實(shí)現(xiàn)自定義。如果應(yīng)用系統(tǒng)使用@ShoppingCart和@ProductCatalog注解數(shù)據(jù)庫(kù),客戶端代碼就會(huì)綁定他們的描述,代碼聲明它在需要可讀時(shí)的依賴,另外使CanDI與其配置提供自身需要的資源。

本文在XML中配置有一個(gè)@Red資源,用戶可以通過這種方式對(duì)個(gè)性化資源進(jìn)行配置。資源客戶端Set-Servlet在使用形容詞注解聲明成員:

例子:SetServlet.java

public class SetServlet extends HttpServlet{

private@Red MyResource_red;

private@Blue MyResource_blue;

...

XML文件很短卻很有用,只需要個(gè)性化表達(dá),而不需要綁定或者做其他連接。數(shù)據(jù)庫(kù)和JMS隊(duì)列需要配置數(shù)據(jù)庫(kù)驅(qū)動(dòng)和增加形容詞綁定。如果希望配置對(duì)用戶有用,應(yīng)用程序的資源也可以配置在XML中,對(duì)于服務(wù)特定的內(nèi)部類則不必配置。在例子中,用戶可以對(duì)資源中的data成員變量進(jìn)行配置,并且可以對(duì)實(shí)現(xiàn)類進(jìn)行選擇。

Bean的XML配置需要三塊信息:驅(qū)動(dòng)類、用于綁定注解的描述以及需要個(gè)性化的數(shù)據(jù)。驅(qū)動(dòng)類是最重要的,CanDI通過XML標(biāo)簽的方式使用類,通過XML名字空間的方式使用包。在查詢XML文件時(shí),驅(qū)動(dòng)類最先體現(xiàn)出它的重要性。在例子中是驅(qū)動(dòng)類。

...

例子:BlueResourceBean實(shí)例的配置

在CanDI中,綁定注解也是一個(gè)XML標(biāo)簽,通過類名稱和所在的包表示。類和注解使用大寫首字母的名字來(lái)匹配類名字,XML屬性使用小寫。這種區(qū)分類和成員的方式提高了XML的可讀性。

例子:@Blue配置

資源的屬性使用標(biāo)準(zhǔn)Bean樣式的名字,設(shè)置了Bean的setData屬性。CanDI將XML字符串值轉(zhuǎn)換為屬性的真實(shí)值。在這個(gè)例子中,轉(zhuǎn)換是繁瑣的,CanDI可以轉(zhuǎn)換整形、雙精度、枚舉、類、URL等等數(shù)據(jù)類型。在resin.xml和resin-web.xml文件中可以把Bean配置成所有Resin Bean所具有的特性,Resin本身的設(shè)計(jì)就是使用CanDI進(jìn)行內(nèi)部配置的。

xmlns:example="urn:java:example">

blue resource

red resource

例子:resin-web.xml

綁定類型應(yīng)該使用可描述的形容詞,這樣注入的描述看起來(lái)比較清晰。其他人看到代碼就會(huì)立刻理解哪些是使用的資源。由于它的重要性以及這只是少數(shù)的個(gè)性化注解,本文的@Blue綁定注解就是使用CanDI的@Qualifier注解標(biāo)記的普通Java注解。花費(fèi)時(shí)間選擇一個(gè)好的形容詞名字很重要。

package example;

import static java.lang.annotation.ElementType.*;

import static java.lang.annotation.RetentionPolicy.*;

import java.lang.annotation.*;

import javax.inject.Qualifier;

@Qualifier

@Documented

@Target({TYPE,METHOD,F(xiàn)IELD,PARAMETER})

@Retention(RUNTIME)

public@interface Blue{

例子:Blue.java

資源的實(shí)現(xiàn)很直觀。單例模式的資源,使用@Singleton注解,比如某個(gè)服務(wù)。默認(rèn)情況下,在每個(gè)注入點(diǎn)CanDI都會(huì)注入Bean的新實(shí)例。

package example;

public class BlueResourceBean{

private String_data;

public void setData(String data){

_data=data;

例子:BlueResourceBean.java

5 啟動(dòng)模式

@Startup注解將Bean標(biāo)記為在服務(wù)器啟動(dòng)時(shí)初始化。啟動(dòng)Bean會(huì)在CanDI查詢classpath時(shí)被找到,啟動(dòng)類控制自身的初始化。站在另外一個(gè)角度,有啟動(dòng)類就足夠了,它不需要在XML中配置啟動(dòng)。啟動(dòng)Bean使用@PostConstruct注解的初始化方法啟動(dòng)初始化代碼。

package example;

import javax.annotation.PostConstruct;

import javax.ejb.Startup;

import javax.inject.Inject;

@Startup

public class MyStartupBean{

private@Inject MyService_service;

@PostConstruct

public void init(){

_service.setMessage(this+":initial value");

例子:MyStartupBean.java

6 擴(kuò)展模式

擴(kuò)展架構(gòu)可以使應(yīng)用系統(tǒng)更加靈活且可配置。例如,過濾器、blueprint、客戶action,這種模式可以顯著提升應(yīng)用系統(tǒng)的性能。擴(kuò)展模式使用CanDI的檢索系統(tǒng)來(lái)查找所有擴(kuò)展接口的實(shí)現(xiàn)。和@Any綁定注解一起Instance會(huì)枚舉所有資源的實(shí)現(xiàn)。

CanDI的Instance接口有兩個(gè)用途:使用get()方法返回特定的編程實(shí)例;列出所有實(shí)例的擴(kuò)展可能。Instance實(shí)現(xiàn)了JDK中Iterable接口,這樣就可以在for循環(huán)中使用。每一個(gè)返回實(shí)例都遵守標(biāo)準(zhǔn)的CanDI范圍規(guī)則,同時(shí)返回@Singleton單例模式的單值或者創(chuàng)建默認(rèn)的新實(shí)例。

@Any注解與Instance一起工作用于選定所有符合條件的實(shí)例。綁定類型默認(rèn)是@Inject:

package example;

import javax.inject.Inject;

import javax.enterprise.inject.Any;

import javax.enterprise.inject.Instance;

...

public class GetServlet extends HttpServlet{

@Inject@Any Instance_resources;

public void service(HttpServletRequest request,

HttpServletResponse response)

throws IOException,ServletException{

PrintWriter out=response.getWriter();

for(MyResource resource:_resources){

out.println("resource:"+resource);

例子:GetServlet.java

7 總結(jié)

CanDI作為Caucho公司對(duì)下一代通用依賴注入技術(shù)標(biāo)準(zhǔn)的CDI獨(dú)立實(shí)現(xiàn),已經(jīng)成為Resin4應(yīng)用服務(wù)器的基礎(chǔ),許多功能已經(jīng)超越了JavaEE6 API,并與諸如JUnit、Struts2、Wicket、iBATIS、Quartz以及Spring等流行第三方框架完成了整合,同時(shí)CanDI支持所有EJB和POJO Bean注解,希望POJO bean注解能夠成為未來(lái)JavaEE7的標(biāo)準(zhǔn)規(guī)范之一。

本文主要介紹了在采用CanDI依賴注入技術(shù)開發(fā)企業(yè)級(jí)應(yīng)用系統(tǒng)時(shí)用到的各類注入模式,在實(shí)際研發(fā)過程中,工程師除了需要掌握服務(wù)、資源、啟動(dòng)、擴(kuò)展這幾種模式的特點(diǎn)和使用情景,還需要在特定環(huán)境中完成資源的配置、具體程序的注入等工作,某些時(shí)候?yàn)榱藬U(kuò)展需要,也可能用到第三方類來(lái)完成應(yīng)用程序裝配。

General Dependency Injection Mode Based on Resin

Liu Xiaoke
(Henan Academy of Science and Technology Information,Zhengzhou Henan 450003)

In this paper,we describe four candi design patterns:service,resource configuration,startup and plugin/extension pattern.Based on the service pattern of the application package management data,The resource configuration pattern is the configuration interface between the user and the application,startuppattern used to initialize the application,plugin/extensionpattern for user customization of complex application behavior.

CanDI;dependency injection;annotation;pattern

TP311.52

A

1003-5168(2016)05-0087-05

2016-5-20

劉小可(1981.11-),男,碩士研究生,工程師,研究方向:軟件工程、公共管理。

猜你喜歡
例子形容詞應(yīng)用程序
認(rèn)識(shí)形容詞
《團(tuán)圓之后》:“戲改”的“一個(gè)鮮明的例子”
中華戲曲(2020年1期)2020-02-12 02:29:00
刪除Win10中自帶的應(yīng)用程序
初中英語(yǔ)課堂妙用“舉例子”
形容詞找家
兒童繪本(2017年6期)2017-04-21 23:20:41
用通俗的例子打比方
在數(shù)學(xué)課堂教學(xué)中怎樣舉例
形容詞
關(guān)閉應(yīng)用程序更新提醒
電腦迷(2012年15期)2012-04-29 17:09:47
三星電子將開設(shè)應(yīng)用程序下載商店
边坝县| 五指山市| 柘荣县| 遂溪县| 鄄城县| 永宁县| 会理县| 清水河县| 威宁| 南安市| 玛沁县| 伊宁市| 莱西市| 平乐县| 沅陵县| 古丈县| 蓬莱市| 新余市| 赣榆县| 肇州县| 康保县| 仁布县| 澄城县| 惠来县| 抚远县| 高阳县| 勐海县| 武宁县| 介休市| 镇原县| 衢州市| 兴安县| 疏附县| 平阳县| 永仁县| 东丰县| 孟津县| 上杭县| 明光市| 信丰县| 高平市|