javascript
Spring实战(前言:Spring容器)
Spring容器,顧名思義是用來容納東西的,裝的就是Bean。Spring容器負責創建、配置、管理Bean。spring容器有兩個核心接口:BeanFactory和ApplicationContext接口,后者是前者的子接口。在基于spring的Java EE程序中,所有的組件都被當成Bean來處理,包括數據源對象、hibernate的sessionFactory、事務管理等,程序中的所有Java類都可以被當成spring容器中的bean。
1、spring容器
spring容器的核心接口是BeanFactory,它有一個子接口就是ApplicationContext。ApplicationContext也被稱為spring上下文。
調用者只需要使用getBean()方法即可獲得指定bean的引用。對于大部分的Java程序而言,使用ApplicationContext作為spring容易更為方便。其常用的實現類有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext和AnnotationConfigXmlApplicationContext。如果Java web中使用spring容器,則通常有XmlWebApplicationContext、AnnotationConfigWebApplicationContext兩個容器。
創建spring容器的實例時,必須提供spring容器管理的bean的配置文件,也就是我們常說的spring.xml配置文件。因此在創建beanFactory時配置文件作為參數傳入。xml配置文件一般以resource對象傳入。resource是spring提供的資源訪問接口,通過該接口spring更簡單、透明的訪問磁盤,網絡系統和類路徑上的相關資源。
對于獨立的Java EE應用程序,可以通過如下方法來實例化BeanFactory。
//在當前項目類路徑下搜索配置文件
ApplicationContext appContext = new ClassPathXmlApplicationContext("beans_7_3_3.xml");
//在文件系統搜索配置文件
appContext = new FileSystemXmlApplicationContext("D:\\spring-tool-workspace\\myspring\\src\\beans_7_3_3.xml");
//獲取chinese的Bean,并且返回的類型為Chinese
Person chinese = appContext.getBean("chinese", Chinese.class);
chinese.useAxe();
2、使用ApplicationContext
大部分時間,都不會使用beanFactory實例作為spring容器,而是使用ApplicationContext作為spring容器,因此spring容器也被稱為spring上下文。ApplicationContext增強了beanFactory的功能,提供了很多有用、方便開發的功能。
在web中可以利用如contextLoader的支持類,在web應用啟動的時候自動創建ApplicationContext。
除了提供beanFactory所支持的全部功能外,application還額外的提供如下功能:
① ApplicationContext會默認初始化所有的singleton bean(單例bean),也可以通過配置取消。
② ApplicationContext繼承了messageSource接口,因此提供國際化支持。
③ 資源訪問,比如URL和文件。
④ 事件機制。
⑤ 同時加載多個配置文件。
⑥ 以聲明式方式啟動并創建spring容器。
ApplicationContext包括beanFactory的所有功能,并提供了一些額外的功能,優先使用ApplicationContext。對于在內存消耗的才使用beanFactory。
當系統創建ApplicationContext容器時,會默認初始化singleton bean,包括調用構造器創建該bean的實例,通過元素驅動spring調用setting方法注入所依賴的對象。這就意味著,系統前期創建ApplicationContext會有很大的開銷,但是一旦初始化完成后面獲取bean實例就會擁有較好的性能。為了阻止在使用ApplicationContext作為spring容器初始化singleton bean可以在元素添加lazy-init="true"屬性。
3、ApplicationContext的國際化支持
ApplicationContext接口繼承了MessageSource接口,因此具備國際化功能。
//MessageSource接口提供的國際化的兩個方法
String getMessage(String code, Object [] args, Locale loc){
}
String getMessage(String code, Object[]args, String default, Locale loc){
}
spring國際化的支持,其實是建立在Java國際化的基礎上的。其核心思路將程序中需要國際化的消息寫入資源文件,而代碼中僅僅使用國際化信息響應的key。
4、ApplicationContext的事件機制
ApplicationContext的事件機制是觀察者設計模式的實現。通過ApplicationEvent和ApplicationListener接口實現,前者是被觀察者,后者是觀察者。
spring事件框架有兩個核心的接口:
ApplicationEvent(事件):必須由ApplicationContext來發布。
ApplicationListener(監聽器):實現了此接口就可以擔任容器中的監聽器bean。
實際上,spring的事件機制是由事件(實現ApplicationEvent接口的類)、事件源(也就是spring容器,并且有Java代碼顯示的觸發)、監聽器(ApplicationListener接口實現類)。這就像我們在頁面點擊一個button。button是事件源,單機的這個動作就是事件,處理函數就是監聽器。
以下代碼演示spring事件機制:
import org.springframework.context.ApplicationEvent;
public class EmailEvent extends ApplicationEvent{
private String address;
private String text;
public EmailEvent(Object source) {
super(source);
}
public EmailEvent(Object source, String address, String text) {
super(source);
this.address = address;
this.text = text;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
http://www.senta7.net/content/?729.html
public String getText(www.yacuangyl.com) {
return text;
}
public void setText(String text) {
this.text = text;
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class EmailNotifier implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
//處理email事件
if(event instanceof www.xcdeyiju.com EmailEvent){
EmailEvent email = (EmailEvent) event;
System.out.println(email.getAddress()+" "+email.getText());
}else {
//輸出spring容器的內置事件
System.out.println("其它事件:"+event);
}
}
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans_7_4_4.xml");
EmailEvent emailEvent = applicationContext.getBean("emailEvent",EmailEvent.class);
applicationContext.publishEvent(emailEvent);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.jujinyule.com .org/schema/beans"
xmlns:xsi="http://www.yuchengyulegw.com 2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.hnawesm.com org/schema/beans/spring-beans.xsd">
<bean class="EmailNotifier"></bean>
<bean id="emailEvent" class="EmailEvent">
<constructor-arg value="test"></constructor-arg>
<constructor-arg value="123@qq.com"></constructor-arg>
<constructor-arg value="this is a test">www.seocelve.com</constructor-arg>
</bean>
</beans>
從上面的代碼可以看出,事件監聽器不僅監聽到了我們程序顯示觸發的事件,還監聽了spring容器內置的事件。如果實際開發需要,我們可以在spring容器初始化或銷毀時回調自定義方法,就可以通過上面的事件監聽機制來完成。
spring提供了如下幾個內置對象:
ContextRefreshedEvent、ContextStartedEvent、ContextClosedEvent、ContextStoppedEvent、RequestHandledEvent。
5、讓bean獲取spring容器
上面都是通過ApplicationContext創建spring容器,再調用spring容器的getBean()方法獲取bean。這種情況下,程序總是持有spring容器的引用。但是在web應用中,我們可以用聲明式的方法來創建spring容器:在web.xml文件中配置一個監聽,讓這個監聽類幫我們來創建spring容器,前端MVC框架直接調用bean,使用依賴注入功能,無需訪問spring容器本身。
在某些特殊情況下,bean需要實現某個功能(比如:bean需要輸出國際化信息,或向spring容器發布事件),這些功能都需要借助spring容器來完成。就是說我們需要將spring容器作為一個bean來注入到其它bean中,只不過spring容器bean是一個容器級別的bean。
為了讓bean獲取它所在容器的引用,可以讓bean實現beanFactoryAware接口。該接口只有一個方法setBeanFactory(BeanFactory beanFactory)方法,方法的beanFactory參數指向spring容器,會由spring容器注入。我們bean中定義一個setter方法后,通常都是由在配置文件中配置元素來驅動spring容器來注入依賴bean的,但是這里我們并沒有這樣做,這是因為一個bean如果實現了beanFactory接口,spring在創建該bean時,會自動注入spring容器本身。與beanFactoryAware接口類似的還有BeanNameAware、ResourceLoaderAware接口,這些接口都會提供類似的setter方法,這些方法會由spring容器來注入。
下面我們來演示一個示例,這個示例中的Person類中的sayHi()方法將輸出國際化消息,這就需要Person獲取Spring容器,借助Spring容器來完成國際化。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="messagSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages/message</value>
</list>
</property>
</bean>
<bean id="person" class="com.container.Person">
</bean>
</beans>
package com.container;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Locale;
public class Person implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void sayHello(String name){
Locale locale = Locale.getDefault(Locale.Category.FORMAT);
String myName = applicationContext.getMessage("name",new String[]{name},Locale.US);
System.out.println(myName);
}
public static void main(String[] args) {
System.out.println(Person.class.getClassLoader().getResource(".").getPath());
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans_7_4_5.xml");
Person p = applicationContext.getBean("person",Person.class);
p.sayHello("江疏影");
}
}
message_zh_CN.properties國際化資源文件
name=CH \u4F60\u597D,{0}
message_en_US.properties國際化資源文件
轉載于:https://www.cnblogs.com/qwangxiao/p/11325322.html
總結
以上是生活随笔為你收集整理的Spring实战(前言:Spring容器)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android IPC系列(一):AID
- 下一篇: AngularJS中ui-router全