javascript
Spring中的容器
1.Spring容器
Spring容器最基本的接口就是BeanFactory, 負責配置,創建和管理bean。我們通常不直接使用BeanFactory接口,而是使用其子接口ApplicationContext.
接口ApplicationContext常用實現類是FileSystemXmlApplicationContext和ClassPathXmlApplicationContext等。后者最常用。
ApplicationContext的實例就是一個容器,Spring容器的意義在于創建和初始化類對象,管理類的依賴關系。
2.ApplicationContext的事件機制
AppicationContext的事件機制是觀察者模式的實現,按以下方式可以實現。
- 首先我們需要自定義一個事件類,此事件類是需要繼承ApplicationEvent類
- 然后我們定義一個監聽類,監聽類作為一個Spring容器中的bean,同時需要實現ApplicationListner接口
- 然后我們就可以使用ApplicationContext的實例發布事件,相應監聽類的實例(bean)負責監聽具體的事件
下面是一個簡單的例子,
?事件類,必須繼承ApplicationEvent,是否為Spring容器的bean無所謂,
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 }?
監聽類,必須作為Spring容器的bean,同時需要實現ApplicationListener接口,重寫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("郵件內容:"+emailEvent.getText()); 14 } else { 15 System.out.println("其他事件:"+evt); 16 } 17 } 18 19 }?
將監聽類配置進Spring容器配置文件中,并沒有什么特殊之處,
<bean class="spi.EmailNotifier" />?
下面寫一個測試類,
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 }?
執行測試類,發現我們不僅監聽到了想要監聽的事件EmailEvent,同時還有一個系統事件ContextRefreshedEvent也被監聽到了,輸出如下,
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 郵件內容:this is a test?
3.ApplicationContext的國際化支持
ApplicationContext接口繼承了MessageSource接口,因此具有國際化功能。MessageSource接口提供了getMessage(...)方法用來進行字符串轉換。
Spring要實現國際化,需要將MessageSource的實例配置成Spring容器中的bean,在bean的屬性(即依賴注入)中配置國際化文件,
1 <!-- ApplicationContext的實例將會查找是否有messageSource的實例并初始化它 --> 2 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> 3 <!-- 這里即依賴注入 --> 4 <property name="basenames"> 5 <list> 6 <!-- 在這里添加國際化配置文件 --> 7 <value>message</value> 8 </list> 9 </property> 10 </bean>?
為此我們需要創建兩份國際化配置文件,第一份為英語,文件名 message_en_US.properties,內容如下,
1 str1=welcome,{0} 2 str2=now is : {0}?
第二份為中文,文件名為message.properties,內容如下,
1 str1=歡迎,{0} 2 str2=現在時間是:{0}?
由于這個文件包含了非西歐字符,因此我們用java自帶的native2ascii進行轉換,命令為
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?
轉換后得到message_zh_CN.properties文件即可。
接著寫一個測試類,
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 }?
我們分別在中文環境和英文環境測試了兩個字符串str1和str2,得到結果如下,
1 歡迎,孫悟空 2 現在時間是:17-2-3 上午1:31 3 welcome,孫悟空 4 now is : 2/3/17 1:31 AM?
上面的文字“孫悟空”因為是直接寫在代碼里面,不屬于properties配置文件的,因此在中英文結果都保留原來的文字。
4.讓Bean獲取Spring容器
如果需要讓Bean主動獲取它所在的Spring容器的引用,可以讓該Bean實現BeanFactoryAware接口,并實現setBeanFactory(BeanFactory beanFactory)方法。
下面是一個例子,
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 }?
將這個類作為一個普通bean配置進Spring中,
<bean id="getContextViaBean" class="spi.GetContextViaBean" />?
下面寫一個測試類,來實現前面的國際化的功能,
1 public static void test4() { 2 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); 3 GetContextViaBean bean = ctx.getBean("getContextViaBean", GetContextViaBean.class); 4 bean.SayHi("孫悟空"); 5 }?
執行結果為,
1 welcome,孫悟空?
與前面國際化方式相比,其實本質上沒有區別,只不過前面的國際化是在測試類中,直接使用ApplicationContext的實例調用MessageSource的getMessage()方法,
而這里是在Bean中,主動去獲取所在容器(ApplicationContext)的引用,并在beanzhong通過ApplicationContext的引用調用了MessageSource的getMessage()方法。
?
轉載于:https://www.cnblogs.com/fysola/p/6361932.html
總結
以上是生活随笔為你收集整理的Spring中的容器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 按要求罗列所有字符串字符序列
- 下一篇: Codeforces Round #39