手寫Spring框架-叁
前言
本章繼續實現ioc的最后一部分——容器事件和事件監聽器
- ApplicationEvent:事件基類,繼承自java.util.EventObject
- ApplicationListener:事件監聽器接口,包含onApplicationEvent方法,給用戶實現的
- ApplicationEventMulticaster:事件廣播器接口,負責管理監聽器和發布事件
- SimpleApplicationEventMulticaster:廣播器的簡單實現,同步調用監聽器
- AbstractApplicationEventMulticaster:廣播器的抽象基類,實現了監聽器的管理和事件匹配邏輯
正文
首先定義和實現事件
事件基類
public abstract class ApplicationEvent extends EventObject {
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public ApplicationEvent(Object source) {
super(source);
}
}
容器事件
public class ApplicationContextEvent extends ApplicationEvent {
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public ApplicationContextEvent(Object source) {
super(source);
}
public final ApplicationContext getApplicationContext() {
return (ApplicationContext) getSource();
}
}
關閉事件
public class ContextClosedEvent extends ApplicationContextEvent{
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public ContextClosedEvent(Object source) {
super(source);
}
}
刷新事件
public class ContextRefreshedEvent extends ApplicationContextEvent{
/**
* Constructs a prototypical Event.
*
* @param source The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public ContextRefreshedEvent(Object source) {
super(source);
}
}
事件廣播器
定義事件廣播器接口
在事件廣播器中定義了添加監聽和刪除監聽的方法以及一個廣播事件的方法 multicastEvent 最終推送事件消息也會經過這個接口方法來處理誰該接收事件。
public interface ApplicationEventMulticaster {
/**
* Add a listener to be notified of all events.
* @param listener the listener to add
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
* Remove a listener from the notification list.
* @param listener the listener to remove
*/
void removeApplicationListener(ApplicationListener<?> listener);
/**
* Multicast the given application event to appropriate listeners.
* @param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);
}
管理監聽器
AbstractApplicationEventMulticaster 是對事件廣播器的公用方法提取,在這個類中可以實現一些基本功能,避免所有直接實現接口放還需要處理細節。
除了像 addApplicationListener、removeApplicationListener,這樣的通用方法,這里這個類中主要是對 getApplicationListeners 和 supportsEvent 的處理。
getApplicationListeners 方法主要是摘取符合廣播事件中的監聽處理器,具體過濾動作在 supportsEvent 方法中。
在 supportsEvent 方法中,主要包括對Cglib、Simple不同實例化需要獲取目標Class,Cglib代理類需要獲取父類的Class,
普通實例化的不需要。接下來就是通過提取接口和對應的 ParameterizedType 和 eventClassName,方便最后確認是否為子類和父類的關系,以此證明此事件歸這個符合的類處理。
public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanFactoryAware {
public final Set<ApplicationListener<ApplicationEvent>> applicationListeners = new LinkedHashSet<>();
private BeanFactory beanFactory;
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
applicationListeners.add((ApplicationListener<ApplicationEvent>) listener);
}
@Override
public void removeApplicationListener(ApplicationListener<?> listener) {
applicationListeners.remove(listener);
}
@Override
public final void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
protected Collection<ApplicationListener> getApplicationListeners(ApplicationEvent event) {
LinkedList<ApplicationListener> allListeners = new LinkedList<>();
for (ApplicationListener<ApplicationEvent> listener : applicationListeners) {
if (supportsEvent(listener, event)) allListeners.add(listener);
}
return allListeners;
}
/**
* 監聽器是否對該事件感興趣
*/
protected boolean supportsEvent(ApplicationListener<ApplicationEvent> applicationListener, ApplicationEvent event) {
Class<? extends ApplicationListener> listenerClass = applicationListener.getClass();
// 按照 CglibSubclassingInstantiationStrategy、SimpleInstantiationStrategy 不同的實例化類型,需要判斷后獲取目標 class
// 如果監聽器是 CGLIB 代理,需要取父類,否則會拿到代理類而不是原始類
Class<?> targetClass = ClassUtils.isCglibProxyClass(listenerClass) ? listenerClass.getSuperclass() : listenerClass;
// 拿監聽器泛型類型
// 獲取實現的接口
Type genericInterface = targetClass.getGenericInterfaces()[0];
// 獲取泛型實參---如UserCreatedEvent
// public class MyListener implements ApplicationListener<UserCreatedEvent> { }
Type actualTypeArgument = ((ParameterizedType) genericInterface).getActualTypeArguments()[0];
// 把泛型類型轉成字符串類名
//最后可以用 Class.forName(className) 得到 Class 對象
String className = actualTypeArgument.getTypeName();
Class<?> eventClassName;
try {
eventClassName = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new BeansException("wrong event class name: " + className);
}
// 判定此 eventClassName 對象所表示的類或接口與指定的 event.getClass() 參數所表示的類或接口是否相同,或是否是其超類或超接口。
// isAssignableFrom是用來判斷子類和父類的關系的,或者接口的實現類和接口的關系的,默認所有的類的終極父類都是Object。如果A.isAssignableFrom(B)結果是true,證明B可以轉換成為A,也就是A可以由B轉換而來。
return eventClassName.isAssignableFrom(event.getClass());
}
}
事件分發
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
setBeanFactory(beanFactory);
}
@SuppressWarnings("unchecked")
@Override
public void multicastEvent(final ApplicationEvent event) {
for (final ApplicationListener listener : getApplicationListeners(event)) {
listener.onApplicationEvent(event);
}
}
}
事件發布者的定義與實現
ApplicationEventPublisher 是整個一個事件的發布接口,所有的事件都需要從這個接口發布出去。
public interface ApplicationEventPublisher {
/**
* Notify all listeners registered with this application of an application
* event. Events may be framework events (such as RequestHandledEvent)
* or application-specific events.
* @param event the event to publish
*/
void publishEvent(ApplicationEvent event);
}
在AbstractApplicationContext 類中添加事件發布機制
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
private ApplicationEventMulticaster applicationEventMulticaster;
@Override
public void refresh() throws BeansException {
// 1. 創建 BeanFactory,并加載 BeanDefinition
refreshBeanFactory();
// 2. 獲取 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 3. 添加 ApplicationContextAwareProcessor,讓繼承自 ApplicationContextAware 的 Bean 對象都能感知所屬的 ApplicationContext
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 4. 在 Bean 實例化之前,執行 BeanFactoryPostProcessor (Invoke factory processors registered as beans in the context.)
// 真正執行了
invokeBeanFactoryPostProcessors(beanFactory);
// 5. BeanPostProcessor 需要提前于其他 Bean 對象實例化之前執行注冊操作
// 只是注冊,加入到執行鏈中,并沒有執行
registerBeanPostProcessors(beanFactory);
// 6. 初始化事件發布者
initApplicationEventMulticaster();
// 7. 注冊事件監聽器
registerListeners();
// 8. 提前實例化單例Bean對象
beanFactory.preInstantiateSingletons();
// 9. 發布容器刷新完成事件
finishRefresh();
}
private void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, applicationEventMulticaster);
}
private void registerListeners() {
Collection<ApplicationListener> applicationListeners = getBeansOfType(ApplicationListener.class).values();
for (ApplicationListener listener : applicationListeners) {
applicationEventMulticaster.addApplicationListener(listener);
}
}
private void finishRefresh() {
publishEvent(new ContextRefreshedEvent(this));
}
/**
* 獲取所有實現了BeanPostProcessor的Bean,將它加到BeanPostProcessor執行鏈,getBeansOfType()返回的就是beanDefinitionMap的遍歷順序,也就是注冊順序
* 即BeanPostProcessor執行鏈里執行的順序是它的注冊順序
* 如果需要改變執行的優先級,可以實現 PriorityOrdered 或 Ordered 接口
* @param beanFactory
*/
private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {
beanFactory.addBeanPostProcessor(beanPostProcessor);
}
}
/**
* 直接執行了BeanFactoryProcessor
* @param beanFactory
*/
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
for (BeanFactoryPostProcessor beanFactoryPostProcessor:beanFactoryPostProcessorMap.values()){
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
}
}
/**
* 門面+委托模式的應用,在這里再次實現getBeansOfType只是因為ApplicationContext是對用戶使用的,
* 這里再次實現只是提供一個門面,但是真正實現還是委托給DefaultListableBeanFactory去做
* @param type
* @return
* @param <T>
* @throws BeansException
*/
@Override
public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
return getBeanFactory().getBeansOfType(type);
}
@Override
public String[] getBeanDefinitionNames() {
return getBeanFactory().getBeanDefinitionNames();
}
@Override
public Object getBean(String beanName) {
return getBeanFactory().getBean(beanName);
}
@Override
public Object getBean(String beanName, Object... args) {
return getBeanFactory().getBean(beanName, args);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return getBeanFactory().getBean(name, requiredType);
}
@Override
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
}
@Override
public void close() {
// 發布容器關閉事件
publishEvent(new ContextClosedEvent(this));
// 執行銷毀單例bean的銷毀方法
getBeanFactory().destroySingletons();
}
@Override
public void publishEvent(ApplicationEvent event) {
applicationEventMulticaster.multicastEvent(event);
}
protected abstract void refreshBeanFactory() throws BeansException;
protected abstract ConfigurableListableBeanFactory getBeanFactory();
}
ioc部分類關系圖


浙公網安備 33010602011771號