三、容器的功能扩展

三、容器的功能扩展

1.示例代码

ApplicationContext bf = new ClassPathXmlApplicationContext("beanFactoryText.xml");

2.ClassPathXmlApplicationContext

public ClassPathXmlApplicationContext(String configLocation) throws BeansException 		{
		this(new String[] {configLocation}, true, null);
	}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

3.核心方法refresh()

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
            //1.准备刷新的上下文环境
			prepareRefresh();
			//2.初始化BeanFactory,并进行XML文件读取
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			//3.功能扩展
			prepareBeanFactory(beanFactory);

			try {
				//4.由子类扩展:允许在子类中对beanFactory进行后处理
				postProcessBeanFactory(beanFactory);
				//5.激活BeanFactoryPostProcessor
				invokeBeanFactoryPostProcessors(beanFactory);
				//6.注册BeanPostProcessor
				registerBeanPostProcessors(beanFactory);
				//7.初始化消息资源
				initMessageSource();
				//8.初始化事件广播器
				initApplicationEventMulticaster();
				//9.在子类实现来初始化其他bean
				onRefresh();
				//10.注册监听器
				registerListeners();
				//11.实例化所有剩余(非延迟初始化)单例
				finishBeanFactoryInitialization(beanFactory);
				//12.完成刷新
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				destroyBeans();
				cancelRefresh(ex);
				throw ex;
			}

			finally {
				resetCommonCaches();
			}
		}
	}
3.1初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。
///   prepareRefresh方法逻辑  //
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
//子类重写该方法进行个性化的属性处理及设置
initPropertySources();
//对属性进行验证
getEnvironment().validateRequiredProperties();
3.2初始化BeanFactory,并进行xml读取。

​ ClassPathXmlApplicationContext包含BeanFactory所提供的一切特征,在这一步骤中将会复用BeanFactory中的配置文件读取解析及其他功能。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}
protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
            //创建DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
            //指定序列化id
			beanFactory.setSerializationId(getId());
            //定制beanFactory设置allowBeanDefinitionOverriding和allowCircularReferences
			customizeBeanFactory(beanFactory);
            //加载BeanDefinition 与第一章中的加载一样
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
                //将beanFactory设置到applicationContext
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
3.3功能扩展
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		//告诉内部beanFactory使用上下文的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
    	//设置beanFactory的spring表达式语言处理器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    	//为beanFactory增加一个默认的propertyEditor属性注册编辑器
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 添加一个BeanPostProcessor,对下面的几个Aware类型bean进行注入
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    	//设置几个忽略自动装配的接口
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		//设置了几个自动装配的特殊规则
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 注册早期的后置处理器以检测ApplicationListeners的bean
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 检测LoadTimeWeaver并准备编织(如果找到)
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			//为类型匹配设置临时ClassLoader
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 注册默认的系统环境bean.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

设置忽略依赖知识点
在这里插入图片描述

3.4子类实现对beanFactory进行后置处理
///比如子类AbstractRefreshableWebApplicationContext中///

beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
3.5激活各种BeanFactory处理器
//在上下文中调用注册为bean的工厂处理器
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// 如果在此期间找到,则检测LoadTimeWeaver并准备编织
		// 例如通过ConfigurationClassPostProcessor注册的@Bean方法
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

调用BeanFactoryPostProcessor逻辑图

步骤一在这里插入图片描述

步骤二在这里插入图片描述

3.6注册BeanPostProcessor

​ 逻辑和前面激活BeanFactoryPostProcessor相似,从容器中找到所有BeanPostProcessor类型的bean,然后根据PriorityOrdered,Ordered,MergedBeanDefinitionPostProcessor,进行分组并且排序,然后全部注册进beanPostProcessors里。

3.7初始化消息资源

​ 应用:spring国际化

3.8初始化ApplicationEventMulticaster

​ 如果用户自定义了事件广播器,那么使用用户自定义的事件广播器。

​ 如果用户没有自定义事件广播器,那么使用默认的ApplicationEventMulticaster.

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

当产生Spring事件的时候会默认使用SimpleApplicationEventMulticaster的multicastEvent方法来广播事件,遍历所有监听器,并使用监听器中的onApplicationEvent方法来进行监听器的处理。而对于每个监听器来说其实都可以获取到产生的事件,但是是否进行处理则由事件监听器决定。

3.9由子类实现其它特殊bean的初始化
//比如AbstractRefreshableWebApplicationContext实现类中
protected void onRefresh() {
		this.themeSource = UiApplicationContextUtils.initThemeSource(this);
	}
3.10注册监听器
		//硬编码方式注册的监听器处理
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}
		
		//配置文件注册的监听器处理
		//不要在这里初始化FactoryBeans,我们需要保留所有常规bean未初始化,让后处理器应用于它们!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}
		//发布早期事件
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
3.11实例化所有剩余(非延迟初始化)单例
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 初始化此上下文的转换服务(ConversionService)
		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));
		}
		//如果没有bean后处理器(例如PropertyPlaceholderConfigurer bean)在此之前注册任何内容,则注册默认的嵌入值解析器(主要用于注解属性值的解析)。
		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}
		//尽早初始化LoadTimeWeaverAware bean以允许尽早注册其变换器
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// 停止使用临时ClassLoader进行类型匹配
		beanFactory.setTempClassLoader(null);

		// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理
		beanFactory.freezeConfiguration();

		// 实例化所有剩余(非延迟初始化)单例。
		beanFactory.preInstantiateSingletons();
	}

ApplicationContext实现的默认行为就是在启动时将所有单例bean提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext实例会创建并配置所有的单例bean。

/DefaultListableBeanFactory类//
public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

可以看到方法最终又是调用了第二章中获取实例的方法

3.12完成刷新

​ 完成刷新过程,通知声明周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知对应监听器。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值