亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ApplicationContext(備用)

系統 1761 0

Spring 源碼分析:ApplicationContext- -

??????????????????????????????????????

?

分析ApplicationContext
?????? Spring的bean包支持通過編碼方式管理和操作bean的基本功能,ApplicationContext則以Framework的方式提供BeanFactory的所有功能。使用ApplicationContext,你可以讓系統加載你的bean(例如,在Servlet容器初始化ContextLoaderServlet時,通過ContextLoader類加載Spring Framework),而不是使用編碼方式來加載。
?????? ApplicationContext接口是context包的基礎,位于org.springframework.context包里,提供了BeanFactory的所有功能。除此之外, ApplicationContext為了支持Framework的工作方式,提供了以下的功能:
?????? l.MessageSource,提供了語言信息的國際化支持
????? 2.提供資源(如URL和文件系統)的訪問支持
????? 3.為實現了ApplicationListener接口的bean提供了事件傳播支持
??????4.為不同的應用環境提供不同的context,例如支持web應用的XmlWebApplicationContext類

????? 下面的源代碼分析主要集中在ApplicationContext接口特有的功能上,如國際化支持,資源訪問和bean的事件傳播。

我的問題
?????? 現在我的問題是,ApplicationContext是如何實現上面提到的功能的?下面的分析將作出回答。

準備測試用例
?????? 1.?首先在類路徑根目錄編寫測試國際化支持的testmsg.xml,并將它加入Spring IDE的管理范圍:
???????<beans>
??????????? <bean id="messageSource"?class="org.springframework.context.support.ResourceBundleMessageSource">
???????????????? <property name="basenames">
????????????????????? <list>
??????????????????????????? <value>message</value>
??????????????????????</list>
???????????????? </property>
??????????? </bean>
?????? </beans>

???????2.?編寫測試用例,測試國際化支持和資源訪問的功能。
?????????? public class MsgTest extends TestCase {
??????????????? ?ApplicationContext ctx = null;
???????????????? public MsgTest(String arg0) {
?????????????????????? super(arg0);
???????????????? }
???????????????? protected void setUp() throws Exception {
?????????????????????? super.setUp();
?????????????????????? ctx = new FileSystemXmlApplicationContext("testmsg.xml");
???????????????? }
??????????????? ?public void testMessageResource() {
?????????????????????? Object[] args = {"我", "你"};
?????????????????????? String msg = ctx.getMessage("hello", args, Locale.CHINA);
?????????????????????? //System.out.println("msg=" + msg);
????????????????????? ?assertEquals("我和你", msg);
????????????????????? ?Resource rs = ctx.getResource("classpath:log4j.properties");
????????????????????? ?assertTrue(rs.exists());
??????????????? }
?????????? }

?????? 3.?在類路徑根目錄創建屬性文件message.properties,內容為hello={0}和{1}。
?
?????? 此時運行TestCase,果然不出所料,Junit視圖的測試狀態是紅條。將打印msg變量的語句打開,重新測試,發現"和"字是亂碼。
?????? 在message.properties文件中將"和"字改為ASCII碼\u548c,重新運行TestCase,綠條,測試通過。
?????? 將testmsg.xml中bean的id改為messageSource1,重新運行測試,出現紅條,測試失敗,說明bean的名稱必須是messageSource,這點值得注意。至于其中的原因稍后說明。

ApplicationContext類圖
?????? ApplicationContext接口相關的類圖如下,其中getParent和publishEvent方法分別支持分層的context和事件傳播功能。
?

?
??????
?????? 如以上的類繼承層次圖所示,ApplicationContext接口通過繼承BeanFactory,MessageSource和ResourceLoader三個接口,分別支持管理和操作bean的功能,語言信息的國際化支持以及對資源訪問的支持。
?????? AbstractApplicationContect是ApplicationContext的抽象實現類,它的繼承層次較為紊亂,我覺得這里應該進行代碼重構。AbstractXmlApplicationContext是AbstractApplicationContext的子類,提供了對XML配置文件的支持,它有三個子類,分別用于不同的應用環境。
?????? 對于MessageSource,Spring提供了兩個bean實現,ResourceBundleMessageSource和ReloadableResourceBundleMessageSource。前者提供了訪問Properties文件的支持,后者添加了無需重啟JVM,重新加載Properties文件的支持。

ApplicationContext的國際化和資源訪問支持
?????? 1.?如類層次圖所示,在我們的例子中,FileSystemXmlApplicationContext使用DefaultListableBeanFactory裝載和解釋testmsg.xml配置文件(參見代碼分析的BeanFactory部分)。

?????? 2.?FileSystemXmlApplicationContext根據配置文件的BeanDefinition創建ResourceBundleMessageSource,加載<list>元素定義的Properties文件,并保存在AbstractApplicationContext的屬性中。當客戶程序調用getMessage方法時,AbstractApplicationContext調用ResourceBundleMessageSource的getMessage方法返回Message信息。

?????? 3.?至于上節提到的MessageSource的id只能是messageSource,是因為AbstractApplicationContext的initMessageSource()方法中,有這樣一段代碼:
?????????????????? this.messageSource = (MessageSource)
?????????????????? getBean(MESSAGE_SOURCE_BEAN_NAME);
?????????? 其中MESSAGE_SOURCE_BEAN_NAME的定義為:
?????????????????? static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
?????????? 原因找到了,其實只要稍做代碼重構,即可消除這個缺陷。

?????? 4.?如類層次圖所示,AbstractApplicationContext繼承了DefaultResourceLoader,當客戶程序調用getResource方法時,使用父類中實現的方法來處理。
?
ApplicationContext的事件傳播

準備測試用例
?????? 1.?首先編寫測試用例。
?????????? public class SenderBeanTest extends TestCase {
??????????????? ApplicationContext ctx = null;
??????????????? protected void setUp() throws Exception {
??????????????????? super.setUp();
??????????????????? ctx = new FileSystemXmlApplicationContext("testlistener.xml");
??????????????? }
??????????????? public void testSendEmail() {
?????????????????? ?SenderBean sender = (SenderBean)ctx.getBean("sender");
?????????????????? ?String msg = sender.sendMessage("test message");
??????????????????? assertEquals("test message", msg);
??????????????? }
???????????}
?????? 2.?接著編寫testlistener.xml配置文件。
???????????<beans>
?????????????? <bean id="sender" class="unittest.SenderBean"/>
?????????????? <bean id="listener" class="unittest.MessageListener"/>
?????????? </beans>
?????? 3.?最后編寫SenderBean,MessageListener和MessageEvent類。
?????????? public class SenderBean implements ApplicationContextAware {
????????????????? private ApplicationContext applicationContext;
????????????????? public void setApplicationContext(ApplicationContext applicationContext)
???????????????????????? ?? throws BeansException {
?????????????????????? ?this.applicationContext = applicationContext;
????????????????? }
????????????????? public String sendMessage(String msg) {
??????????????????????? MessageEvent event = new MessageEvent(msg);
??????????????????????? this.applicationContext.publishEvent(event);
??????????????????????? return msg;
???????????????? ?}
??????????? }
?
??????????? public class MessageListener implements ApplicationListener {
???????????????? ?public void onApplicationEvent(ApplicationEvent event) {
??????????????????????? if (event instanceof MessageEvent) {
????????????????????????????? System.out.println("I got the message:" + event.getSource());
??????????????????????? }
????????????????? }
??????????? }
?
??????????? public class MessageEvent extends ApplicationEvent {
???????????????? ?public MessageEvent(Object source) {
??????????????????????? super(source);
??????????????????????? System.out.println(this.getTimestamp() + ":" + source);
????????????????? }
??????????? }
?????????? 運行測試案例SenderBeanTest,綠條,測試通過。Console窗口出現以下DEBUG信息:
?????????? ……
?????????? 796 DEBUG support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'sender'
?????????? 1085553911796:test message
?????????? 796 DEBUG support.FileSystemXmlApplicationContext - Publishing event in context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=13549765]: unittest.MessageEvent[source=test message]
?????????? I got the message:test message

ApplicationContext有關事件的類圖
????????ApplicationContext事件傳播的類結構圖如下。
?
?
事件傳播的實現
?????? 1.?FileSystemXmlApplicationContext的構造器調用AbstractApplicationContext的refresh方法。如圖所示,refresh方法調用refreshListeners方法。
?????? 2.?AbstractApplicationContext的refreshListeners方法使用BeanFactory的getBeanOfType方法得到所有ApplicationListener類(本例中是MessageListener),并使用addListener方法把它們都放入ApplicationEventMulticasterImpl的Set容器中(eventListeners變量)。
?????? 3.?如圖所示,SenderBean實現ApplicationContextAware接口,并通過setApplicationContext方法注入ApplicationContext對象實例。
???????4.?當調用SenderBean類sendMessage方法時,AbstractApplicationContext調用publishEvent方法。
?????? 5.?AbstractApplicationContext類的publishEvent方法調用ApplicationEventMulticasterImpl類的onApplicationEvent方法。
?????? 6.?ApplicationEventMulticasterImpl通知Set容器中所有的ApplicationListener對象,調用它們的onApplicationEvent方法。
?
?????? 從以上的過程可以看出,ApplicationContext將事件通知所有的ApplicationListener。如果ApplicationListener的子類(如MessageListener)只想接受指定的事件類型,需要自己編寫過濾代碼,如例子中的if (event instanceof MessageEvent)。

ApplicationContext(備用)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日本xx视频| 兽王高清完整在线观看 | 七七久久综合 | 精品国产综合区久久久久久 | 日日夜夜骑| 99热这里只有精品国产免费 | 国产精品久久久久影视不卡 | 亚洲国产精品一区二区三区 | 久久精品一区二区三区不卡 | 香蕉福利久久福利久久香蕉 | 日本aaaa精品免费视频 | 七七七久久久久人综合 | 国内精品视频一区二区八戒 | 真91视频| 久久国产亚洲精品麻豆 | 亚洲综合精品香蕉久久网 | 日韩精品中文字幕在线观看 | 欧美第一页在线观看 | 毛片免费大全 | 日韩字幕一中文在线综合 | 国产精品视频免费观看 | 亚洲精品国产精品乱码视色 | 777kkk亚洲综合欧美色老头 | 一级骚片超级骚在线观看 | 亚洲第五色综合网 | 亚洲国产成人麻豆精品 | 国产国语一级a毛片高清视频 | 国产精品亚洲精品久久成人 | 久久99精品久久久久久黑人 | 色黄网站成年女人色毛片 | 亚洲欧美天堂网 | 四虎国产免费 | 久久99久久精品国产只有 | 精品免费视在线观看 | 99久久精品国产综合男同 | 奇米影视第四色在线 | 天天摸日日舔 | 毛片免费观看久久欧美 | 99久久精品国产一区二区成人 | 99久久精品免费看国产四区 | 婷婷毛片|