Spring原始碼之事件驅動模型
阿新 • • 發佈:2019-02-08
SpringContext中初始化事件釋出者 ###
//spring初始化事件的地方
//spring初始化事件的地方
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
/** 用於事件釋出 */
private ApplicationEventMulticaster applicationEventMulticaster;
/** 靜態指定的監聽器*/
private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>();
//======省略一段程式碼========/
public void refresh() throws BeansException, IllegalStateException {
//======省略一段程式碼========/
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// 檢查監聽器bean並註冊它們。
registerListeners();
//======省略一段程式碼========/
}
//======省略一段程式碼========/
/**
* 初始化ApplicationEventMulticaster.
* <p>如果在上下文中沒有定義,則使用SimpleApplicationEventMulticaster。
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
//獲取bean工廠
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//先找工廠中ApplicationEventMulticaster是否有對應的例項(註冊過)
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {//沒有對應的例項,則自己初始化一個,可以看到沒有初始化執行緒次,所以預設是同步呼叫
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
/**
* 新增實現ApplicationListener的bean作為監聽器
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// 首先註冊靜態指定的監聽器。
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
/**
*不要在這裡初始化FactoryBeans:我們需要將所有常規的bean保留為初始化,以便後bean後置處理器適用於它們!
*/
//查詢所有ApplicationListener型別的類
//includeNonSingletons為false表示只取單例Bean,true則不是
//allowEagerInit為true表示立刻載入,false表示延遲載入。
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
//釋出事件
public void publishEvent(ApplicationEvent event) {
Assert.notNull(event, "Event must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Publishing event in " + getDisplayName() + ": " + event);
}
//獲取applicationEventMulticaster物件,呼叫multicastEvent(event)方法
getApplicationEventMulticaster().multicastEvent(event);
if (this.parent != null) {
this.parent.publishEvent(event);
}
}
}
//可以看到,如果要實現非同步的事件釋出,id必須為“applicationEventMulticaster”
<bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster">
<!-- 注入任務執行器 這樣就實現了非同步呼叫(缺點是全域性的,要麼全部非同步,要麼全部同步(刪除這個屬性即是同步)) -->
<property name="taskExecutor" ref="executor"/>
</bean>
事件ApplicationEvent
//第一部分:spring事件訊息物件
public class EventObject implements java.io.Serializable {
private static final long serialVersionUID = 5516075349620653480L;
/**
* 事件最初發生的物件。
*/
protected transient Object source;
//構造方法
public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");
this.source = source;
}
public Object getSource() {
return source;
}
public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
//抽象類
public abstract class ApplicationEvent extends EventObject {
/** use serialVersionUID from Spring 1.2 for interoperability */
private static final long serialVersionUID = 7099057708183571937L;
/** System time when the event happened */
private final long timestamp;
/**
* Create a new ApplicationEvent.
* @param source the component that published the event (never {@code null})
*/
public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}
/**
* Return the system time in milliseconds when the event happened.
*/
public final long getTimestamp() {
return this.timestamp;
}
}
目標(釋出事件者)ApplicationEventMulticaster (核心)
//第二部分:應用程式事件廣播介面
public interface ApplicationEventMulticaster {
/**
* 新增一個監聽器bean
* @param listener the listener to add
*/
void addApplicationListener(ApplicationListener listener);
/**
* 新增一個監聽器的beanName
* @param listenerBeanName the name of the listener bean to add
*/
void addApplicationListenerBean(String listenerBeanName);
/**
* 刪除一個監聽器bean
* @param listener the listener to remove
*/
void removeApplicationListener(ApplicationListener listener);
/**
* 新增一個監聽器beanName
* @param listenerBeanName the name of the listener bean to add
*/
void removeApplicationListenerBean(String listenerBeanName);
/**
* 刪除所有在這個Multicaster註冊的監聽者。
*/
void removeAllListeners();
/**
* 將給定的應用程式事件組播到適當的偵聽器。
* @param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);
}
//標記介面
public interface Aware {
}
//標記可以設定BeanFactory
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
//標記可以設定bean的類載入器
public interface BeanClassLoaderAware extends Aware {
void setBeanClassLoader(ClassLoader classLoader);
}
//完成了預設實現,應用程式事件廣播抽象類
public abstract class AbstractApplicationEventMulticaster
implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
//監聽者(內部持有:監聽例項 和 監聽者beanName)
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);
//類加器: 不為null時,則檢查 eventType和sourceType是否由給定的ClassLoader或其父級載入。
private ClassLoader beanClassLoader;
//bean工廠:用於獲取defaultRetriever中listenerBeanName所對應的bean例項
private BeanFactory beanFactory;
//新增一個監聽器bean
public void addApplicationListener(ApplicationListener listener) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.add(listener);
this.retrieverCache.clear();
}
}
//新增一個監聽器beanName
public void addApplicationListenerBean(String listenerBeanName) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
this.retrieverCache.clear();
}
}
//刪除一個監聽器bean
public void removeApplicationListener(ApplicationListener listener) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.remove(listener);
this.retrieverCache.clear();
}
}
//刪除一個監聽器beanName
public void removeApplicationListenerBean(String listenerBeanName) {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
this.retrieverCache.clear();
}
}
//刪除所有監聽器
public void removeAllListeners() {
synchronized (this.defaultRetriever) {
this.defaultRetriever.applicationListeners.clear();
this.defaultRetriever.applicationListenerBeans.clear();
this.retrieverCache.clear();
}
}
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
if (this.beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory) {
this.beanClassLoader = ((ConfigurableBeanFactory) beanFactory).getBeanClassLoader();
}
}
private BeanFactory getBeanFactory() {
if (this.beanFactory == null) {
throw new IllegalStateException("ApplicationEventMulticaster cannot retrieve listener beans " +
"because it is not associated with a BeanFactory");
}
return this.beanFactory;
}
//返回所有監聽者例項列表
protected Collection<ApplicationListener> getApplicationListeners() {
synchronized (this.defaultRetriever) {
return this.defaultRetriever.getApplicationListeners();
}
}
//返回與給定事件型別匹配的ApplicationListeners集合。 不匹配的聽眾早日被排除在外。
protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) {
Class<? extends ApplicationEvent> eventType = event.getClass();
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);
// 先走快取
ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
//快取中沒有
if (this.beanClassLoader == null ||
//在給定的上下文中,檢查給定的類是否是快取安全的,即是否由給定的ClassLoader或其父級載入。
(ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
(sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
// Fully synchronized building and caching of a ListenerRetriever
synchronized (this.defaultRetriever) {
retriever = this.retrieverCache.get(cacheKey);
if (retriever != null) {
return retriever.getApplicationListeners();
}
retriever = new ListenerRetriever(true);
Collection<ApplicationListener> listeners = retrieveApplicationListeners(eventType, sourceType, retriever);
//放入快取
this.retrieverCache.put(cacheKey, retriever);
return listeners;
}
}
else {
//沒有ListenerRetriever快取 - >不需要synchronization
return retrieveApplicationListeners(eventType, sourceType, null);
}
}
/**
* 實際檢索給定事件和源型別的應用程式監聽器列表。
* @param eventType the application event type
* @param sourceType the event source type
* @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
* @return the pre-filtered list of application listeners for the given event and source type
*/
private Collection<ApplicationListener> retrieveApplicationListeners(
Class<? extends ApplicationEvent> eventType, Class<?> sourceType, ListenerRetriever retriever) {
LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
Set<ApplicationListener> listeners;
Set<String> listenerBeans;
synchronized (this.defaultRetriever) {
listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners);
listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
}
for (ApplicationListener listener : listeners) {
if (supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListeners.add(listener);
}
allListeners.add(listener);
}
}
if (!listenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : listenerBeans) {
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
if (retriever != null) {
retriever.applicationListenerBeans.add(listenerBeanName);
}
allListeners.add(listener);
}
}
}
OrderComparator.sort(allListeners);
return allListeners;
}
//確定給定的偵聽器是否支援給定的事件。
protected boolean supportsEvent(
ApplicationListener listener, Class<? extends ApplicationEvent> eventType, Class<?> sourceType) {
SmartApplicationListener smartListener = (listener instanceof SmartApplicationListener ?
(SmartApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
}
/**
* Cache key for ListenerRetrievers, based on event type and source type.
* 基於事件型別和源型別的ListenerRetrievers快取鍵。
*/
private static class ListenerCacheKey {
//事件型別
private final Class<?> eventType;
//source型別
private final Class<?> sourceType;
public ListenerCacheKey(Class<?> eventType, Class<?> sourceType) {
this.eventType = eventType;
this.sourceType = sourceType;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
ListenerCacheKey otherKey = (ListenerCacheKey) other;
return ObjectUtils.nullSafeEquals(this.eventType, otherKey.eventType) &&
ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType);
}
@Override
public int hashCode() {
return ObjectUtils.nullSafeHashCode(this.eventType) * 29 + ObjectUtils.nullSafeHashCode(this.sourceType);
}
}
//Helper類封裝了一組特定的目標監聽器,可以有效地檢索預過濾的監聽器。
//<p>每個事件型別和源型別都會快取此幫助器的一個例項。
private class ListenerRetriever {
//監聽者bean例項列表
public final Set<ApplicationListener> applicationListeners;
//監聽者bean名稱列表
public final Set<String> applicationListenerBeans;
//預過濾
private final boolean preFiltered;
public ListenerRetriever(boolean preFiltered) {
this.applicationListeners = new LinkedHashSet<ApplicationListener>();
this.applicationListenerBeans = new LinkedHashSet<String>();
this.preFiltered = preFiltered;
}
//返回監聽者例項列表
public Collection<ApplicationListener> getApplicationListeners() {
LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
for (ApplicationListener listener : this.applicationListeners) {
allListeners.add(listener);
}
if (!this.applicationListenerBeans.isEmpty()) {
//獲取給定的bean工廠
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : this.applicationListenerBeans) {
//給定類載入載入監聽者bean例項(標記一)
ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
//需要預過濾 則先判斷 (標記一載入例項)是否在allListeners中;不在,則新增
if (this.preFiltered || !allListeners.contains(listener)) {
allListeners.add(listener);
}
}
}
//排序
OrderComparator.sort(allListeners);
return allListeners;
}
}
}
//spring預設實現的
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
//執行緒池
private Executor taskExecutor;
//構造方法
public SimpleApplicationEventMulticaster() {
}
/**
* Create a new SimpleApplicationEventMulticaster for the given BeanFactory.
*/
public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
setBeanFactory(beanFactory);
}
//設定Executor例項用來執行執行應用程式偵聽器。
public void setTaskExecutor(Executor taskExecutor) {
this.taskExecutor = taskExecutor;
}
protected Executor getTaskExecutor() {
return this.taskExecutor;
}
@SuppressWarnings("unchecked")
public void multicastEvent(final ApplicationEvent event) {
for (final ApplicationListener listener : getApplicationListeners(event)) {
Executor executor = getTaskExecutor();
//利用執行緒次呼叫監聽者方法(非同步,需使用者指定Executor例項)
if (executor != null) {
executor.execute(new Runnable() {
public void run() {
listener.onApplicationEvent(event);
}
});
}
else {//遍歷監聽器(預設:同步執行)
listener.onApplicationEvent(event);
}
}
}
}
監聽器 EventListener
public interface EventListener {
}
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
/**
* 處理事件訊息的地方
* @param event the event to respond to
*/
void onApplicationEvent(E event);
}