javascript
Spring笔记——2.使用Spring容器
Spring有兩個核心接口:BeanFactory和ApplicationContext。而ApplicationContext是BeanFactory的子接口,都可以代表Spring容器,用于產生管理Bean們。我們經常使用ApplicationContext以及它的實現類ClassPathXmlApplicationContext。當創建ApplicationContext時,會實例化所有的單例Bean,花銷較大,但之后性能較好。如果為bean設置lazy-init為true,則不會在開始初始化。
國際化支持
ApplicationContext集成了MessageSource接口,具有國際化功能。當程序創建ApplicationContext容器時,架構會去找messageSource這個Bean,然后接口中的getMessage(String code,Object[] args, Locale loc)與getMessage(String code, Object[] args, String default, Local loc)就會被交給messageSource這個bean使用。如果沒找到,則會穿件一個StaticMessageSource,由它調用兩個方法。其中第二個參數的對象組是為了填補國際化文件中的{0}、{1}這些的。這個bean的id規定死了必須是messageSource,而實現類也規定死了必須這么寫。
<bean?id="messageSource"?class="org.springframework.context.support.ResourceBundleMessageSource"> <property?name="basenames"> <list> <value>包名/資源文件組1</value> <value>包名1/包名2/資源文件組2</value> </list> </property> </bean>由于容器已經集成了MessageResource這個接口,因此容器實例能夠直接調用getMessage這個方法。
String?hello=act.getMessage("hello",?new?String[]?{"A"},?Locale.getDefault());ApplicationContext的事件機制
通過ApplicationEvent抽象類(必須由ApplicationContext發布)和ApplicationListener(容器中任意的bean承擔)接口可以實現ApplicationContext的事件處理。如果容器中有一個bean實現了ApplicationListener這個接口,每當ApplicaitonContext發布ApplicationEvent,ApplicationLIstener Bean將會自動被觸發。我們都知道事件機制需要事件源,事件和監聽器。事件源此處是ApplicationContext,必須由java程序顯式觸發。
事件如下,必須繼承ApplicationEvent父類
package?com.cm.event; import?org.springframework.context.ApplicationEvent; public?class?EmailEvent?extends?ApplicationEvent?{private?String?address;private?String?text;public?String?getAddress()?{return?address;}public?void?setAddress(String?address)?{this.address?=?address;}public?String?getText()?{return?text;}public?void?setText(String?text)?{this.text?=?text;}public?EmailEvent(Object?source,String?address,String?text)?{super(source); this.address=address; this.text=text;//?TODO?Auto-generated?constructor?stub}public?EmailEvent(Object?source)?{super(source);//?TODO?Auto-generated?constructor?stub} }上述代碼中提供了兩個不同的構造函數。構造函數需要被傳入一個bean實例。監聽器如下,需要實現ApplicationListener接口:
public?class?EmailNotifier?implements?ApplicationListener?{ @Override public?void?onApplicationEvent(ApplicationEvent?arg0)?{//?TODO?Auto-generated?method?stubif(arg0?instanceof?EmailEvent){EmailEvent?emailEvent=(EmailEvent)arg0;System.out.println("需要發送郵件的接收地址"+emailEvent.getAddress());System.out.println("需要發送郵件的征文"+emailEvent.getText());}else{System.out.println("other!!!!!!!!!!!"+arg0);}} }上述代碼中的方法就是對接口的實現。這個方法的形參就是容器發布的事件的類型。由于所有實現了接口的監聽器都會在事件發布時被啟動,因此我們需要這個參數來判斷到底是哪個實例出發的事件。我們會得到的 注意我們在xml中配置的只有監聽器,而事件是顯式觸發的(當然有些時候也需要配置,不過本例中我們還是使用了new,因為沒有用到依賴關系)
<bean?class="com.cm.event.EmailNotifier">顯式觸發事件
ApplicationContext?act=new?ClassPathXmlApplicationContext("beans.xml"); EmailEvent?ele=new?EmailEvent("test","1357@qq.com","my?email"); act.publishEvent(ele);總結如下:當程序發布了一個事件(內置事件不需要手動發布,會自動監聽),xml中的所有監聽器就會自動被啟動,并執行相應程序。
讓Bean獲取Spring容器
之前的例子中我們都是先new一個ApplicationContext實例,然后通過實例操作。這種情況下,程序中總是持有Spring容器的引用。Web應用中,Spring容器通常采用聲明方式配置產生。開發者需要在web.xml中設一個listener,它會負責初始化容器,前段mvc框架可以直接調用bean,無需通過容器。但是有的時候,bean需要實現某個功能比如國際化(這個bean中需要使用ctx,使用的是容器實例的getMessage方法),而他們必須借助容器才能完成,因此還是要先得到容器,再實現功能。
為了能讓某一個bean得到他的爸爸:容器,可以讓這個bean實現BeanFactoryAware接口,它里面有一個gesetBeanFactory方法,它的參數就是指向創建它的容器。這個set方法是由Spring調用的。?
public?class?Aperson?implements?ApplicationContextAware?{ private?ApplicationContext?ctx;@Overridepublic?void?setApplicationContext(ApplicationContext?arg0)throws?BeansException?{//?TODO?Auto-generated?method?stub this.ctx=arg0;} public?void?sayHi(String?name){System.out.println(ctx.getMessage(arg0,?arg1)); } }架構會掃面所有的bean看哪個有接口ApplicationContextAware,然后使用set方法傳入容器實例。此bean的測試程序省略。。。測試中調用了sayHi方法,而這個方法自己沒法完成功能,需要ctx的getMessage,因此它得想法得到容器實例。那就實現一個接口吧,Srping會為這個接口的set方法傳入一個容器實例,將傳入值賦給自己的成員變量吧!
轉載于:https://blog.51cto.com/mengcao/1690407
總結
以上是生活随笔為你收集整理的Spring笔记——2.使用Spring容器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: scala 学习笔记(07) 一等公民的
- 下一篇: rest架构