javascript
Spring中的容器
1.Spring容器
Spring容器最基本的接口就是BeanFactory, 負(fù)責(zé)配置,創(chuàng)建和管理bean。我們通常不直接使用BeanFactory接口,而是使用其子接口ApplicationContext.
接口ApplicationContext常用實(shí)現(xiàn)類(lèi)是FileSystemXmlApplicationContext和ClassPathXmlApplicationContext等。后者最常用。
ApplicationContext的實(shí)例就是一個(gè)容器,Spring容器的意義在于創(chuàng)建和初始化類(lèi)對(duì)象,管理類(lèi)的依賴(lài)關(guān)系。
2.ApplicationContext的事件機(jī)制
AppicationContext的事件機(jī)制是觀察者模式的實(shí)現(xiàn),按以下方式可以實(shí)現(xiàn)。
- 首先我們需要自定義一個(gè)事件類(lèi),此事件類(lèi)是需要繼承ApplicationEvent類(lèi)
- 然后我們定義一個(gè)監(jiān)聽(tīng)類(lèi),監(jiān)聽(tīng)類(lèi)作為一個(gè)Spring容器中的bean,同時(shí)需要實(shí)現(xiàn)ApplicationListner接口
- 然后我們就可以使用ApplicationContext的實(shí)例發(fā)布事件,相應(yīng)監(jiān)聽(tīng)類(lèi)的實(shí)例(bean)負(fù)責(zé)監(jiān)聽(tīng)具體的事件
下面是一個(gè)簡(jiǎn)單的例子,
?事件類(lèi),必須繼承ApplicationEvent,是否為Spring容器的bean無(wú)所謂,
1 package spi; 2 3 import org.springframework.context.ApplicationEvent; 4 5 public class EmailEvent extends ApplicationEvent { 6 private String address; 7 public String getAddress() { 8 return address; 9 } 10 public void setAddress(String address) { 11 this.address = address; 12 } 13 public String getText() { 14 return text; 15 } 16 public void setText(String text) { 17 this.text = text; 18 } 19 private String text; 20 public EmailEvent(Object source) { 21 super(source); 22 } 23 public EmailEvent(Object source, String address, String text) { 24 super(source); 25 this.address = address; 26 this.text = text; 27 } 28 }?
監(jiān)聽(tīng)類(lèi),必須作為Spring容器的bean,同時(shí)需要實(shí)現(xiàn)ApplicationListener接口,重寫(xiě)onApplicationEvent方法
1 package spi; 2 3 import org.springframework.context.ApplicationEvent; 4 import org.springframework.context.ApplicationListener; 5 6 public class EmailNotifier implements ApplicationListener { 7 8 @Override 9 public void onApplicationEvent(ApplicationEvent evt) { 10 if (evt instanceof EmailEvent) { 11 EmailEvent emailEvent = (EmailEvent)evt; 12 System.out.println("郵件地址:"+emailEvent.getAddress()); 13 System.out.println("郵件內(nèi)容:"+emailEvent.getText()); 14 } else { 15 System.out.println("其他事件:"+evt); 16 } 17 } 18 19 }?
將監(jiān)聽(tīng)類(lèi)配置進(jìn)Spring容器配置文件中,并沒(méi)有什么特殊之處,
<bean class="spi.EmailNotifier" />?
下面寫(xiě)一個(gè)測(cè)試類(lèi),
1 public static void test2() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 EmailEvent ele = new EmailEvent("test", "test@test.com", "this is a test"); 4 ctx.publishEvent(ele); 5 }?
執(zhí)行測(cè)試類(lèi),發(fā)現(xiàn)我們不僅監(jiān)聽(tīng)到了想要監(jiān)聽(tīng)的事件EmailEvent,同時(shí)還有一個(gè)系統(tǒng)事件ContextRefreshedEvent也被監(jiān)聽(tīng)到了,輸出如下,
1 其他事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.support.ClassPathXmlApplicationContext@1873eb2: startup date [Fri Feb 03 01:19:21 CST 2017]; root of context hierarchy] 2 郵件地址:test@test.com 3 郵件內(nèi)容:this is a test?
3.ApplicationContext的國(guó)際化支持
ApplicationContext接口繼承了MessageSource接口,因此具有國(guó)際化功能。MessageSource接口提供了getMessage(...)方法用來(lái)進(jìn)行字符串轉(zhuǎn)換。
Spring要實(shí)現(xiàn)國(guó)際化,需要將MessageSource的實(shí)例配置成Spring容器中的bean,在bean的屬性(即依賴(lài)注入)中配置國(guó)際化文件,
1 <!-- ApplicationContext的實(shí)例將會(huì)查找是否有messageSource的實(shí)例并初始化它 --> 2 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> 3 <!-- 這里即依賴(lài)注入 --> 4 <property name="basenames"> 5 <list> 6 <!-- 在這里添加國(guó)際化配置文件 --> 7 <value>message</value> 8 </list> 9 </property> 10 </bean>?
為此我們需要?jiǎng)?chuàng)建兩份國(guó)際化配置文件,第一份為英語(yǔ),文件名 message_en_US.properties,內(nèi)容如下,
1 str1=welcome,{0} 2 str2=now is : {0}?
第二份為中文,文件名為message.properties,內(nèi)容如下,
1 str1=歡迎,{0} 2 str2=現(xiàn)在時(shí)間是:{0}?
由于這個(gè)文件包含了非西歐字符,因此我們用java自帶的native2ascii進(jìn)行轉(zhuǎn)換,命令為
1 cd C:\Program Files (x86)\Java\jdk1.7.0_79\bin\ 2 native2ascii C:\PROJECT\JavaBasic\PROJECT_JavaBasic\src\message.properties C:\PROJECT\JavaBasic\PROJECT_JavaBasic\src\message_zh_CN.properties?
轉(zhuǎn)換后得到message_zh_CN.properties文件即可。
接著寫(xiě)一個(gè)測(cè)試類(lèi),
1 public static void test3() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 String str1 = ctx.getMessage("str1", new String[]{"孫悟空"}, 4 Locale.getDefault(Locale.Category.FORMAT)); 5 String str2 = ctx.getMessage("str2", new Object[]{new Date()}, 6 Locale.getDefault(Locale.Category.FORMAT)); 7 System.out.println(str1); 8 System.out.println(str2); 9 10 String str3 = ctx.getMessage("str1", new String[]{"孫悟空"}, 11 Locale.US); 12 String str4 = ctx.getMessage("str2", new Object[]{new Date()}, 13 Locale.US); 14 System.out.println(str3); 15 System.out.println(str4); 16 }?
我們分別在中文環(huán)境和英文環(huán)境測(cè)試了兩個(gè)字符串str1和str2,得到結(jié)果如下,
1 歡迎,孫悟空 2 現(xiàn)在時(shí)間是:17-2-3 上午1:31 3 welcome,孫悟空 4 now is : 2/3/17 1:31 AM?
上面的文字“孫悟空”因?yàn)槭侵苯訉?xiě)在代碼里面,不屬于properties配置文件的,因此在中英文結(jié)果都保留原來(lái)的文字。
4.讓Bean獲取Spring容器
如果需要讓Bean主動(dòng)獲取它所在的Spring容器的引用,可以讓該Bean實(shí)現(xiàn)BeanFactoryAware接口,并實(shí)現(xiàn)setBeanFactory(BeanFactory beanFactory)方法。
下面是一個(gè)例子,
1 package spi; 2 3 import java.util.Locale; 4 5 import org.springframework.beans.BeansException; 6 import org.springframework.context.ApplicationContext; 7 import org.springframework.context.ApplicationContextAware; 8 9 public class GetContextViaBean implements ApplicationContextAware { 10 private ApplicationContext ctx; 11 @Override 12 public void setApplicationContext(ApplicationContext ctx) 13 throws BeansException { 14 this.ctx = ctx; 15 } 16 public void SayHi(String name) { 17 System.out.println(ctx.getMessage("str1", new String[]{name}, Locale.US)); 18 } 19 20 }?
將這個(gè)類(lèi)作為一個(gè)普通bean配置進(jìn)Spring中,
<bean id="getContextViaBean" class="spi.GetContextViaBean" />?
下面寫(xiě)一個(gè)測(cè)試類(lèi),來(lái)實(shí)現(xiàn)前面的國(guó)際化的功能,
1 public static void test4() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 GetContextViaBean bean = ctx.getBean("getContextViaBean", GetContextViaBean.class); 4 bean.SayHi("孫悟空"); 5 }?
執(zhí)行結(jié)果為,
1 welcome,孫悟空?
與前面國(guó)際化方式相比,其實(shí)本質(zhì)上沒(méi)有區(qū)別,只不過(guò)前面的國(guó)際化是在測(cè)試類(lèi)中,直接使用ApplicationContext的實(shí)例調(diào)用MessageSource的getMessage()方法,
而這里是在Bean中,主動(dòng)去獲取所在容器(ApplicationContext)的引用,并在beanzhong通過(guò)ApplicationContext的引用調(diào)用了MessageSource的getMessage()方法。
?
轉(zhuǎn)載于:https://www.cnblogs.com/fysola/p/6361932.html
總結(jié)
以上是生活随笔為你收集整理的Spring中的容器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 按要求罗列所有字符串字符序列
- 下一篇: Codeforces Round #39