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

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條評論
主站蜘蛛池模板: 91综合精品网站久久 | 亚洲第一成人在线 | 国产大片中文字幕 | 精品国产一区二区三区四区不 | 老子影院午夜伦手机在线看 | 一级寡妇乱色毛片全18 | 激情五月婷婷综合网 | 日本一区二区三区久久 | 国产精品成人免费综合 | 日本欧美一区二区三区在线观看 | 玖玖精品在线视频 | 久久久精品在观看999 | 看全色黄大色大片免费视频 | 天天干天天射天天操 | 91国内精品线免费播放 | 国产特级毛片aaaaaa高清 | 亚洲黄色成人 | 国产一区二三区 | 五月天婷婷缴情五月免费观看 | 亚洲视频在线不卡 | 日韩精品一区二区三区国语自制 | 成人日韩精品 | 亚洲精品亚洲九十七页 | 毛片在线高清免费观看 | a毛片免费全部播放完整成 a毛片免费全部在线播放毛 | 免费精品国产自产拍在 | 欧美日韩亚洲无线码在线观看 | 福利毛片| 男人草女人视频 | 国产一区二区三区视频 | 九九热免费在线视频 | 深夜福利国产福利视频 | 国产乱码精品一区二区三区卡 | 在线播放国产视频 | 国产成人精品免费大全 | 国产精品自线在线播放 | 国产成人精品午夜免费 | 亚洲成人黄色 | 国产精品视频福利一区二区 | 日本一级大黄毛片免费基地 | 26uuu欧美日本|