深入理解Spring原始碼之IOC 擴充套件原理BeanFactoryPostProcessor和事件監聽ApplicationListener

擊水三千里發表於2019-01-09

2.BeanFactoryPostProcessor

一個好的框架必備的特性至少得有開閉原則,可擴充套件性BeanFactoryPostProcessor也是Spring可擴充套件性的一個體現,我們讀一下這個介面的原始碼

public interface BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     * @param beanFactory the bean factory used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

允許我們在工廠裡所有的bean被載入進來後但是還沒初始化前,對所有bean的屬性進行修改也可以add屬性值。

bean工廠後置處理器—>構造方法—>init-method。

 3、ApplicationListener 

3.1、測試程式碼: 

package com.atguigu.ext;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.atguigu.bean.Blue;
 
@ComponentScan("com.atguigu.ext")
@Configuration
public class ExtConfig {
	
	@Bean
	public Blue blue(){
		return new Blue();
	}

}

 


import org.junit.Test;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.atguigu.ext.ExtConfig;

public class IOCTest_Ext {
	
	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);
		
		
		//釋出事件;
		applicationContext.publishEvent(new ApplicationEvent(new String("我釋出的時間")) {
		});
		
		applicationContext.close();
	}

}

 

3.2、ApplicationListener的應用

 ApplicationListener:監聽容器中釋出的事件。事件驅動模型開發;
        public interface ApplicationListener<E extends ApplicationEvent>
          監聽 ApplicationEvent 及其下面的子事件;
  
       步驟:
          1)、寫一個監聽器(ApplicationListener實現類)來監聽某個事件(ApplicationEvent及其子類)
              @EventListener;
              原理:使用EventListenerMethodProcessor處理器來解析方法上的@EventListener;
  
          2)、把監聽器加入到容器;
          3)、只要容器中有相關事件的釋出,我們就能監聽到這個事件;
                  ContextRefreshedEvent:容器重新整理完成(所有bean都完全建立)會發布這個事件;
                  ContextClosedEvent:關閉容器會發布這個事件;
          4)、釋出一個事件:
                  applicationContext.publishEvent();

3.3、ApplicationListener的原理 

   【事件釋出流程】:
     publishEvent(new ContextRefreshedEvent(this));
              1)、獲取事件的多播器(派發器):getApplicationEventMulticaster()
              2)、multicastEvent派發事件:
              3)、獲取到所有的ApplicationListener;
                   for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
                   1)、如果有Executor,可以支援使用Executor進行非同步派發;
                       Executor executor = getTaskExecutor();
                   2)、否則,同步的方式直接執行listener方法;invokeListener(listener, event);
                    拿到listener回撥onApplicationEvent方法; 

 註解:為了便於理解下面只保留了最核心的原始碼,只在關鍵的呼叫地方打中文註釋

 
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {
 
 
	@Override
	public void publishEvent(ApplicationEvent event) {
		publishEvent(event, null);
	}

 
	protected void publishEvent(Object event, ResolvableType eventType) {
 
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}
		else {
			applicationEvent = new PayloadApplicationEvent<Object>(this, event);
			if (eventType == null) {
				eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
			}
		}
 
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}
 
	}

 
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

	private Executor taskExecutor;

	private ErrorHandler errorHandler;


	@Override
	public void multicastEvent(ApplicationEvent event) {
		multicastEvent(event, resolveDefaultEventType(event));
	}

	@Override
	public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			Executor executor = getTaskExecutor();
			if (executor != null) {
				executor.execute(new Runnable() {
					@Override
					public void run() {
						invokeListener(listener, event);
					}
				});
			}
			else {
				invokeListener(listener, event);
			}
		}
	}


}

3.4、 @EventListener

3.4.1、基於註解的方式建立監聽器:

import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

@Service
public class UserInfoService {
	
	@EventListener(classes={ApplicationEvent.class})
	public void listen(ApplicationEvent event){
		System.out.println("UserService。。監聽到的事件:"+event);
	}

}

3.4.2 @EventListener註解原理

原理:使用EventListenerMethodProcessor處理器來解析方法上的@EventListener;

再看SmartInitializingSingleton  這個類的原理即可

public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware 

SmartInitializingSingleton 原理:->執行這個方法afterSingletonsInstantiated();

afterSingletonsInstantiated();是在所有bean初始化完成之後呼叫的,

斷點在EventListenerMethodProcessor.afterSingletonsInstantiated()方法上檢視執行流程

1)、ioc容器建立物件並refresh();

2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的單例項bean;

​       1)、DefaultListableBeanFactory.preInstantiateSingletons()->先建立所有的單例項bean;getBean();

​       2)、獲取所有建立好的單例項bean,判斷是否是SmartInitializingSingleton型別的;如果是就呼叫afterSingletonsInstantiated();
 

 public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {

	//ioc容器建立物件並refresh();
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {

			prepareRefresh();

			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			prepareBeanFactory(beanFactory);

			try {

				postProcessBeanFactory(beanFactory);

				invokeBeanFactoryPostProcessors(beanFactory);

				registerBeanPostProcessors(beanFactory);


				initMessageSource();

				initApplicationEventMulticaster();

				onRefresh();

				registerListeners();

				// 初始化剩下的單例項bean
				finishBeanFactoryInitialization(beanFactory);

				finishRefresh();
			}

			catch (BeansException ex) {
 
				destroyBeans();

				cancelRefresh(ex);

				throw ex;
			}

			finally {
 
				resetCommonCaches();
			}
		}
	}

 

}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext, DisposableBean {
 
 
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}
 
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
				@Override
				public String resolveStringValue(String strVal) {
					return getEnvironment().resolvePlaceholders(strVal);
				}
			});
		}
 
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		beanFactory.setTempClassLoader(null);
 
		beanFactory.freezeConfiguration();

                //先建立所有的單例項bean
		beanFactory.preInstantiateSingletons();
	}

 

}
 
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
 
	@Override
	public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}

		 
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

	 
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

 
		for (String beanName : beanNames) {

			Object singletonInstance = getSingleton(beanName);

                       //獲取所有建立好的單例項bean,判斷是否是SmartInitializingSingleton型別的;
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							smartSingleton.afterSingletonsInstantiated();
							return null;
						}
					}, getAccessControlContext());
				}
				else { 
                                         //如果是就呼叫afterSingletonsInstantiated();
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

 
 
}

待續。。。

相關文章