Spring進階之路(2)-ApplicationContext容器以及事件機制
Spring容器最基本的介面是BeanFactory,他負責配置、建立、管理bean,他的子介面之一:ApplicationContext,也叫做spring的上下文。ApplicationContext是BeanFactory的子介面,在web應用中,通常會用到XmlWebApplicationContext、AnnotationCofigWebApplicationContext兩個實現類。
ApplicationContext簡介
系統建立ApplicationContext容器的時候,預設會預先初始化所有的單例的bean,呼叫構造器建立例項物件,然後通過set方法注入依賴的物件例項。這樣的情況下,也就是說會面臨著一個問題,容器在初始化的時候會有較大的效能的消耗,但是一旦初始化完成之後,程式在獲取單例的bean的時候,又會獲得較好的效能。
下面看一個簡單的例子,來理解一下ApplicationContext的初始化流程。
建立如下的一個類。包括無引數的建構函式以及一個set方法。
package com.siti.spring20160228;
public class WangYang {
public WangYang(){
System.out.println("無參的建構函式!");
}
public void setName(String name){
System.out.println("my name is " + name);
}
}
配置檔案中新增這個bean類。
<?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 definitions here --> <bean id = "wy" class = "com.siti.spring20160228.WangYang"> <property name="name" value="wy"></property> </bean> </beans>
測試類,只建立一個ApplicationContext的例項物件。
package com.siti.spring20160228; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160228.xml"); } }
測試結果:
ApplicationContext的事件機制
ApplicationContext的事件機制屬於觀察者設計模式(設計模式篇會在後期專門推出請讀者關注),通過ApplicationEvent和ApplicationListener介面,可以實現ApplicationContext的事件處理。
spring事件機制中ApplicationEvent和ApplicationListener起到重要作用。其中,ApplicationEvent:由ApplicationContext釋出。ApplicationListener可以由容器裡面任何的監聽器bean擔任。
下面以一段例項進行講解
MessageEvent類繼承了ApplicationEvent類,一個事件。
package com.siti.spring20160228.applicationContextListener;
import org.springframework.context.ApplicationEvent;
public class MessageEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
private String messageContent;
public MessageEvent(Object source) {
super(source);
}
public MessageEvent(Object source, String messageContent) {
super(source);
this.messageContent = messageContent;
}
public String getMessageContent() {
return messageContent;
}
public void setMessageContent(String messageContent) {
this.messageContent = messageContent;
}
}
監聽器類實現ApplicationListener介面實現需要實現的這個方法,發生事件的時候會被觸發。
package com.siti.spring20160228.applicationContextListener;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class MessageListener implements ApplicationListener<ApplicationEvent> {
// 容器事件發生的時候觸發方法的執行
@Override
public void onApplicationEvent(ApplicationEvent event) {
if(event instanceof MessageEvent){
MessageEvent messageEvent = (MessageEvent) event;
System.out.println("資訊內容是:" + messageEvent.getMessageContent());
}else{
System.out.println("其他的資訊!" + event.toString());
}
}
}
註冊監聽器,在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 definitions here -->
<bean class = "com.siti.spring20160228.applicationContextListener.MessageListener"></bean>
</beans>
在測試程式中進行測試如下:
package com.siti.spring20160228.applicationContextListener;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext20160228.xml");
MessageEvent event = new MessageEvent("", "my name is wy");
// 釋出事件
context.publishEvent(event);
}
}
列印資訊
其他的資訊!org.springframework.context.event.ContextRefreshedEvent[source=org[email protected]1dff3a2: startup date [Sun Feb 28 14:43:48 CST 2016]; root of context hierarchy]
資訊內容是:my name is wy
列印的資訊中我們看到,打印出來我們監聽到的事件的同時,也監聽到了內建的事件的訊息。
spring的內建事件:
1. ContextRefreshedEvent:ApplicationContext容器初始化或者重新整理的時候會觸發這個事件。
2. ContextStartedEvent:當使用ConfigurableApplicationContext(applicationContext的子介面)介面的start方法啟動ApplicationContext容器的時候觸發這個事件。
3. ContextClosedEvent:當使用ConfigurableApplicationContext(applicationContext的子介面)介面的close方法啟動ApplicationContext容器的時候觸發這個事件。
4. ContextStoppedEvent:當使用ConfigurableApplicationContext(applicationContext的子介面)介面的stop方法啟動ApplicationContext容器的時候觸發這個事件。
5. RequestHandledEvent:web相關的事件,只能用在DispatcherServlet的web應用中,在使用spring作為mvc控制器的時候,處理完使用者的請求後,系統會自動的呼叫。
另外webSocket服務中,還有,SessionConnectedEvent、SessionConnectEvent、SessionDisconnectEvent三個事件。