<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    OMG,到底在尋找什么..................
    (構造一個完美的J2EE系統所需要的完整知識體系)
    posts - 198,  comments - 37,  trackbacks - 0

    原貼地址:http://book.csdn.net/bookfiles/111/1001113461.shtml

    一.Spring IOC反轉控制 BeanFactory

    Spring IoC
    設計的核心是 org.springframework.beans 包,它的設計目標是與 JavaBean 組件一起使用。這個包通常不是由用戶直接使用,而是由服務器將其用作其他多數功能的底層中介。下一個最高級抽象是 BeanFactory 接口,它是工廠設計模式的實現,允許通過名稱創建和檢索對象。 BeanFactory 也可以管理對象之間的關系。

    BeanFactory 支持兩個對象模型。

    單態模型:它提供了具有特定名稱的對象的共享實例,可以在查詢時對其進行檢索。 Singleton 是默認的也是最常用的對象模型,對于無狀態服務對象很理想。

    原型模型:它確保每次檢索都會創建單獨的對象。在每個用戶都需要自己的對象時,原型模型最適合。

    bean 工廠的概念是 Spring 作為 IoC 容器的基礎, IoC 將處理事情的責任從應用程序代碼轉移到框架。 Spring 框架使用 JavaBean 屬性和配置數據來指出必須設置的依賴關系。

    1 BeanFactory

    BeanFactory 實際上是實例化,配置和管理眾多 bean 的容器。這些 bean 通常會彼此合作,因而它們之間會產生依賴。 BeanFactory 使用的配置數據可以反映這些依賴關系(一些依賴可能不像配置數據一樣可見,而是在運行期作為 bean 之間程序交互的函數)。

    一個 BeanFactory 可以用接口 org.springframework.beans.factory.BeanFactory 表示,這個接口有多個實現。最常使用的簡單的 BeanFactory 實現是 org.springframework.beans.factory. xml.XmlBeanFactory (這里提醒一下, ApplicationContext BeanFactory 的子類,所以大多數的用戶更喜歡使用 ApplicationContext XML 形式)。

    雖然大多數情況下,幾乎所有被 BeanFactory 管理的用戶代碼都不需要知道 BeanFactory ,但是 BeanFactory 還是以某種方式實例化。可以使用下面的代碼實例化 BeanFactory 。

    InputStream is = new FileInputStream("beans.xml");
    XmlBeanFactory factory = new XmlBeanFactory(is);

    也可以使用下列代碼實例化 BeanFactory 。

    ClassPathResource res = new ClassPathResource("beans.xml");
    XmlBeanFactory factory = new XmlBeanFactory(res);

    實例化 BeanFactory 還可以采用如下代碼。

    ClassPathXmlApplicationContext appContext = new ClassPathXmlApplication Context(?
    ???new String[] {"applicationContext.xml", "applicationContext-part2. xml"});

    // of course, an ApplicationContext is just a BeanFactory
    BeanFactory factory = (BeanFactory) appContext;

    很多情況下,用戶代碼不需要實例化 BeanFactory ,因為 Spring 框架代碼會做這件事。例如, Web 層提供支持代碼,在 J2EE Web 應用啟動過程中自動載入一個 Spring ApplicationContext 。這個聲明過程在這里描述。

    編程操作 BeanFactory 將會在后面提到,下面部分將集中描述 BeanFactory 的配置。

    一個最基本的 BeanFactory 配置由一個或多個它所管理的 Bean 定義組成。在一個 XmlBeanFactory 中,根節點 beans 中包含一個或多個 bean 元素。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework. org/dtd/spring-beans.dtd"> <beans>?
    ?????? <bean id="..." class="...">
    ???????...
    ?
    ?????</bean>?
    ???????<bean id="..." class="...">
    ????????...
    ???????
    </bean>
    </beans>
    ...

    2 BeanDefinition

    一個 XmlBeanFactory 中的 Bean 定義包括的內容如下。

    classname :這通常是 bean 真正的實現類。但是,如果一個 bean 使用一個靜態工廠方法所創建,而不是被普通的構造函數創建,那么這實際上就是工廠類的 classname

    bean 行為配置元素:它聲明這個 bean 在容器的行為方式(比如 prototype singleton 、自動裝配模式、依賴檢查模式、初始化和析構方法)。

    構造函數的參數和新創建 bean 需要的屬性:舉一個例子,一個管理連接池的 bean 使用的連接數目(即可以指定為一個屬性,也可以作為一個構造函數參數)或者池的大小限制。

    和這個 bean 工作相關的其他 bean :比如它的合作者(同樣可以作為屬性或者構造函數的參數),這個也被叫做依賴。

    上面列出的概念直接轉化為組成 bean 定義的一組元素。這些元素在表 6-1 中列出,它們每一個都有更詳細的說明的鏈接。

    6-1? Bean 定義的解釋

    ???

    ???

    class

    bean 的類

    id name

    bean 的標志符 (id name)

    singleton prototype

    Singleton 的使用與否

    構造函數參數

    設置 bean 的屬性和合作者

    bean 的屬性

    設置 bean 的屬性和合作者

    自動裝配模式

    自動裝配協作對象

    依賴檢查模式

    依賴檢查

    初始化模式

    生命周期接口

    析構方法

    生命周期接口

    意, bean 定義可以表示為真正的接口 org.springframework.beans.factory.config.BeanDefinition 以及它的各種子接口和實現。然而,絕大多數的用戶代碼不需要與 BeanDefination 直接接觸。

    3 bean

    class 屬性通常是強制性的,有兩種用法。在絕大多數情況下, BeanFactory 直接調用 bean 的構造函數來“ new ”一個 bean (相當于調用 new Java 代碼), class 屬性指定了需要創建的 bean 的類。在比較少的情況下, BeanFactory 調用某個類的靜態的工廠方法來創建 bean , class 屬性指定了實際包含靜態工廠方法的那個類(至于靜態工廠方法返回的 bean 的類型是同一個類還是完全不同的另一個類,這并不重要)。

    1 )通過構造函數創建 bean

    當使用構造函數創建 bean 時,所有普通的類都可以被 Spring 使用,并且和 Spring 兼容。這就是說,被創建的類不需要實現任何特定的接口或者按照特定的樣式進行編寫。僅僅指定 bean 的類就足夠了。然而,根據 bean 使用的 IoC 類型,你可能需要一個默認的(空的)構造函數。

    另外, BeanFactory 并不局限于管理真正的 JavaBean ,它也能管理任何你想讓它管理的類。雖然很多使用 Spring 的人喜歡在 BeanFactory 中用真正的 JavaBean (僅包含一個默認的(無參數的)構造函數,在屬性后面定義相對應的 setter getter 方法),但是在你的 BeanFactory 中也可以使用特殊的非 bean 樣式的類。舉例來說,如果你需要使用一個遺留下來的完全沒有遵守 JavaBean 規范的連接池,不要擔心, Spring 同樣能夠管理它。

    使用 XmlBeanFactory 你可以像下面這樣定義你的 bean class

    <bean id="exampleBean" class="examples.ExampleBean"/>
    <bean name="anotherExample" class="examples.ExampleBeanTwo"/>

    至于為構造函數提供(可選的)參數,以及對象實例創建后設置實例屬性,將會在后面敘述。

    2 )通過靜態工廠方法創建 bean

    當你定義一個使用靜態工廠方法創建的 bean ,同時使用 class 屬性指定包含靜態工廠方法的類,這個時候需要 factory-method 屬性來指定工廠方法名。 Spring 調用這個方法(包含一組可選的參數)并返回一個有效的對象,之后這個對象就完全和構造方法創建的對象一樣。用戶可以使用這樣的 bean 定義在遺留代碼中調用靜態工廠。

    下面是一個 bean 定義的例子,聲明這個 bean 要通過 factory-method 指定的方法創建。注意,這個 bean 定義并沒有指定返回對象的類型,只指定包含工廠方法的類。在這個例子中, createInstance 必須是 static 方法。

    <bean id="exampleBean" ?class="examples.ExampleBean2" ?factory-method="createInstance"/>

    至于為工廠方法提供(可選的)參數,以及對象實例被工廠方法創建后設置實例屬性,將會在后面敘述。

    3 )通過實例工廠方法創建 bean

    使用一個實例工廠方法(非靜態的)創建 bean 和使用靜態工廠方法非常類似,調用一個已存在的 bean (這個 bean 應該是工廠類型)的工廠方法來創建新的 bean 。

    使用這種機制, class 屬性必須為空,而且 factory-bean 屬性必須指定一個 bean 的名字,這個 bean 一定要在當前的 bean 工廠或者父 bean 工廠中,并包含工廠方法。而工廠方法本身仍然要通過 factory-method 屬性設置。

    下面是一個例子。

    <!-- The factory bean, which contains a method called??createInstance -->
    <bean id="myFactoryBean"class="...">?
    ? ...
    </bean>

    <!-- The bean to be created via the factory bean -->
    <bean id="exampleBean" ?factory-bean="myFactoryBean" ?factory-method="createInstance"/>

    雖然我們要在后面討論設置 bean 的屬性,但是,這個方法意味著工廠 bean 本身能夠被容器通過依賴注射來管理和配置。

    4 Bean 的標志符( id name

    每一個 bean 都有一個或多個 id (也叫做標志符或名字,這些名詞說的是一回事)。這些 id 在管理 bean BeanFactory ApplicationContext 中必須是惟一的。一個 bean 差不多總是只有一個 id ,但是,如果一個 bean 有超過一個的 id ,那么另外的那些本質上可以認為是別名。

    在一個 XmlBeanFactory 中(包括 ApplicationContext 的形式),你可以用 id 或者 name 屬性來指定 bean id(s) ,并且在這兩個或其中一個屬性中至少指定一個 id 。 id 屬性允許你指定一個 id ,并且它在 XML DTD (定義文檔)中作為一個真正的 XML 元素的 ID 屬性被標記,所以 XML 解析器能夠在其他元素指回向它的時候做一些額外的校驗。正因如此,用 id 屬性指定 bean id 是一個比較好的方式。然而, XML 規范嚴格限定了在 XML ID 中合法的字符。通常這并不是真正限制你,但是,如果你有必要使用這些字符(在 ID 中的非法字符),或者你想給 bean 增加其他的別名,那么你可以通過 name 屬性指定一個或多個 id (用逗號或分號分隔)。

    5 Singleton 的使用與否

    Beans 被定義為兩種部署模式中的一種: singleton non-singleton (后一種也叫做 prototype ,盡管這個名詞用的不精確)。如果一個 bean singleton 形態的,那么就只有一個共享的實例存在,所有和這個 bean 定義的 id 符合的 bean 請求都會返回這個惟一的、特定的實例。

    如果 bean non-singleton prototype 模式部署的話,對這個 bean 的每次請求都會創建一個新的 bean 實例。這對于每個 user 需要一個獨立的 user 對象的情況是非常理想的。

    Beans 默認被部署為 singleton 模式,除非你指定。要記住把部署模式變為 non-singletion prototype )后,每一次對這個 bean 的請求都會導致一個新創建的 bean ,而這可能并不是你真正想要的。所以,僅僅在絕對需要的時候才把模式改成 prototype 。

    在下面這個例子中,兩個 bean 一個被定義為 singleton ,而另一個被定義為 non-singleton prototype )??蛻舳嗣看蜗?/span> BeanFactory 請求都會創建新的 exampleBean ,而 AnotherExample 僅僅被創建一次,在每次對它請求都會返回這個實例的引用。

    <bean id="exampleBean" ?class="examples.ExampleBean" singleton="false"/>
    <bean name="yetAnotherExample" ?class="examples.ExampleBeanTwo" singleton="true"/>

    注意,當部署一個 bean prototype 模式,這個 bean 的生命周期就會有稍許改變。 通過定義, Spring 無法管理一個 non-singleton/prototype bean 的整個生命周期,因為當它創建之后,它被交給客戶端,而且容器根本不再跟蹤它了。當說起 non-singleton/prototype bean 的時候,你可以把 Spring 的角色想像成“ new ”操作符的替代品。從那之后的任何生命周期方面的事情都由客戶端來處理。




    二.Spring IOC反轉控制 ApplicationContext

    beans 包提供了以編程的方式管理和操控 bean 的基本功能,而 context 包增加了 ApplicationContext ,它以一種更加面向框架的方式增強了 BeanFactory 的功能。多數用戶可以以一種完全的聲明式方式來使用 ApplicationContext ,甚至不用去手工創建它,但是卻去依賴像 ContextLoader 的支持類,在 J2EE Web 應用的啟動進程中用它啟動 ApplicationContext 。當然,這種情況下還可以以編程的方式創建一個 ApplicationContext

    Context 包的基礎是位于 org.springframework.context 包中的 ApplicationContext 接口。它是由 BeanFactory 接口集成而來,提供 BeanFactory 所有的功能。為了以一種更像面向框架的方式工作, context 包使用分層和有繼承關系的上下文類,包括:

    1 MessageSource ,提供對 i18n 消息的訪問;
    2 .資源訪問,比如 URL 和文件;
    3 .事件傳遞給實現了 ApplicationListener 接口的 bean ;
    4 .載入多個(有繼承關系)上下文類,使得每一個上下文類都專注于一個特定的層次,比如應用的 Web 層。

    因為 ApplicationContext 包括了 BeanFactory 所有的功能,所以通常建議先于 BeanFactory 使用,除了有限的一些場合,比如在一個 Applet 中,內存的消耗是關鍵的,每千字節都很重要。接下來,敘述 ApplicationContext BeanFactory 的基本能力上增加的功能。

    1 )使用 MessageSource

    ApplicationContext 接口繼承 MessageSource 接口,所以提供了 messaging 功能( i18n 或者國際化)。同 NestingMessageSource 一起使用,就能夠處理分級的信息,這些是 Spring 提供的處理信息的基本接口。讓我們很快瀏覽一下這里定義的方法。

    String getMessage (String code 、 Object[] args 、 String default 、 Locale loc) :這個方法是從 MessageSource 取得信息的基本方法。如果對于指定的 locale 沒有找到信息,則使用默認的信息。傳入的參數 args 被用來代替信息中的占位符,這個是通過 Java 標準類庫的 MessageFormat 實現的。

    String getMessage (String code 、 Object[] args 、 Locale loc) :本質上和上一個方法是一樣的,除了一點區別:沒有默認值可以指定;如果信息找不到,就會拋出一個 NoSuchMessage Exception 。

    String getMessage(MessageSourceResolvable resolvable 、 Locale locale) :上面兩個方法使用的所有屬性都可以封裝到一個叫做 MessageSourceResolvable 的類中,你可以通過這個方法直接使用它。

    ApplicationContext 被加載的時候,它會自動查找在 context 中定義的 MessageSource bean ,這個 bean 必須叫做 message source 。如果找到了這樣的一個 bean ,所有對上述方法的調用將會被委托給找到的 message source 。如果沒有找到 message source , ApplicationContext 將會嘗試查它的父親是否包含這個名字的 bean 。如果有,它將會把找到的 bean 作為 Message Source 。如果它最終沒有找到任何信息源,一個空的 StaticMessageSource 將會被實例化,使它能夠接受上述方法的調用。

    Spring 目前提供了兩個 MessageSource 的實現,它們是 ResourceBundleMessageSource StaticMessageSource 。它們都實現了 NestingMessageSource , 以便能夠嵌套地解析信息。 StaticMessageSource 很少被使用,但是它提供以編程的方式向 source 增加信息。 Resource BundleMessageSource 用得更多一些,我們將提供它的一個例子。

    <beans>?
    ? <bean id="messageSource"
    ?????????????? class="org.springframework.context.support.ResourceBundle MessageSource">

    ??????? <property name="basenames">
    ??????????? <list>
    ?????????????? <value>format</value>
    ??????????????? <value>exceptions</value>
    ??????????????? <value>windows</value>
    ??????????? </list>
    ??????? </property>
    ??? </bean>

    </beans>

    這段配置假定你在 classpath 3 resource bundle ,分別叫做 f format exceptions windows 使用 JDK 通過 ResourceBundle 解析信息的標準方式,任何解析信息的請求都會被處理。

    2 )事件傳遞

    ApplicationContext 中的事件處理是通過 ApplicationEvent 類和 ApplicationListener 接口來提供的。如果上下文中部署了一個實現了 ApplicationListener 接口的 bean ,每次一個 ApplicationEvent 發布到 ApplicationContext 時,那個 bean 就會被通知。實質上,這是標準的 Observer 設計模式。 Spring 提供了 3 個標準事件,如表 6-2 所示。

    6-2? 內置事件

    ???

    ???

    ContextRefreshedEvent

    ApplicationContext 已經初始化或刷新后發送的事件。這里初始化意味著所有的 bean 被裝載, singleton 被預實例化,以及 ApplicationContext 已準備好

    ContextClosedEvent

    當使用 ApplicationContext close() 方法結束上下文的時候發送的事件。這里結束意味著: singleton 被銷毀 ?

    RequestHandledEvent

    一個與 Web 相關的事件,告訴所有的 bean 一個 HTTP 請求已經被響應了(這個事件將會在一個請求結束后被發送)。注意,這個事件只能應用于使用了 Spring DispatcherServlet Web 應用

    同樣也可以實現自定義的事件。通過調用 ApplicationContext publishEvent() 方法,并且指定一個參數,這個參數是你自定義的事件類的一個實例。我們來看一個例子,首先是 ApplicationContext 。

    <bean id="emailer" class="example.EmailBean">?
    ??? <property name="blackList">
    ??????? <list>
    ????????????? <value>black@list.org</value>
    ????????????? <value>white@list.org</value>
    ????????????? <value>john@doe.org</value>
    ??????? </list>
    ??? </property>

    </bean>

    <bean id="blackListListener" class="example.BlackListNotifier">?
    ????<property name="notificationAddress">
    ??????? <value>spam@list.org</value>
    ??? </property>

    </bean>

    然后是實際的bean。

    public class EmailBean implements ApplicationContextAware {

    ??? /** the blacklist */
    ??? private List blackList;
    ??
    ??? public void setBlackList(List blackList) {
    ??????? this.blackList = blackList;
    ??? }
    ?
    ??? public void setApplicationContext(ApplicationContext ctx) {
    ??????? this.ctx = ctx;
    ??? }
    ?
    ??? public void sendEmail(String address, String text) {

    ??????? if (blackList.contains(address)) {
    ??????????? BlackListEvent evt = new BlackListEvent(address, text);
    ??????????? ctx.publishEvent(evt);
    ??????????? return;
    ??????? }
    ?
    ??????? // send email
    ??? }

    }

    public class BlackListNotifier implement ApplicationListener {

    ??? /** notification address */
    ??? private String notificationAddress;

    ???public void setNotificationAddress(String notificationAddress) {
    ??????? this.notificationAddress = notificationAddress;
    ??? }

    ??? public void onApplicationEvent(ApplicationEvent evt) {
    ??????? if (evt instanceof BlackListEvent) {
    ??????????? // notify appropriate person
    ??????? }
    ??? }

    }

    ?

    3 )在 Spring 中使用資源

    很多應用程序都需要訪問資源。 Spring 提供了一個清晰透明的方案,以一種協議無關的方式訪問資源。 ApplicationContext 接口包含一個方法( getResource(String) )負責這項工作。

    Resource 類定義了幾個方法,這幾個方法被所有的 Resource 實現所共享,資源功能如表 6-3 所示。

    6-3? 資源功能

    ???

    ???

    getInputStream()

    InputStream 打開資源,并返回這個 InputStream

    exists()

    檢查資源是否存在,如果不存在,返回 false

    isOpen()

    如果這個資源不能打開多個流,將會返回 true 。因為除了基于文件的資源,一些資源不能被同時多次讀取,它們就會返回 false

    getDescription()

    返回資源的描述,通常是全限定文件名或者實際的 URL

    Spring 提供了幾個 Resource 的實現。它們都需要一個 String 表示的資源的實際位置。依據這個 String , Spring 將會自動為你選擇正確的 Resource 實現。當向 ApplicationContext 請求一個資源時, Spring 首先檢查你指定的資源位置,尋找任何前綴。根據不同的 Application Context 的實現,不同的 Resource 實現可被使用。 Resource 最好是使用 ResourceEditor 來配置,比如 XmlBeanFactory 。




    posted on 2006-11-01 10:39 OMG 閱讀(725) 評論(0)  編輯  收藏 所屬分類: Spring

    <2006年11月>
    2930311234
    567891011
    12131415161718
    19202122232425
    262728293012
    3456789

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    IT風云人物

    文檔

    朋友

    相冊

    經典網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲日本VA午夜在线电影| 精品国产亚洲一区二区三区在线观看 | 亚洲人成色在线观看| 国产在线播放免费| 国产成人免费AV在线播放| 亚洲偷自精品三十六区| 亚洲视频人成在线播放| 波多野结衣在线免费视频| 免费中文字幕视频| 亚洲国产综合自在线另类| 免费jjzz在在线播放国产| 91高清免费国产自产拍2021| 欧美激情综合亚洲一二区| 久久久久亚洲Av片无码v| 日韩精品视频免费在线观看| 久久国产精品成人免费| 久久亚洲精品无码av| 亚洲va在线va天堂va四虎 | 亚洲av无码乱码在线观看野外| 久久大香伊焦在人线免费| 国产精品亚洲专区无码WEB| 亚洲av一综合av一区| 免费一区二区三区四区五区| 8888四色奇米在线观看免费看| 免费播放美女一级毛片| 亚洲白色白色永久观看| 国产AV无码专区亚洲AWWW| 四虎在线视频免费观看| 亚洲视频在线免费看| XXX2高清在线观看免费视频| 亚洲中文无码永久免| 亚洲精品视频专区| 亚洲男人的天堂www| 国产免费av片在线无码免费看| 精品福利一区二区三区免费视频| 一级毛片一级毛片免费毛片| 亚洲欧美国产国产综合一区| 亚洲av乱码一区二区三区香蕉| 久久亚洲精品成人| 久久久久国产成人精品亚洲午夜| 日本免费人成黄页网观看视频|