spring源码解析(容器的功能扩展)

Spring中还提供了另一个接口ApplicationContext,继承了BeanFactory,且包含BeanFactory的所有功能,并额外提供了一些其他的功能。比如国际化支持、事件机制、AOP支持等等。

通过ApplicationContext加载xml文件

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
    }

进入构造器后主要有两个逻辑

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

		super(parent);
		setConfigLocations(configLocations);//设置配置路径并支持多个配置文件
		if (refresh) {
			refresh();
		}
	}

在setConfigLocations中对路径做了解析,比如${var}这样的,会从环境变量中取到var的变量进行替换,而refresh中基本上包含了ApplicationContext的全部功能。

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 刷新上下文环境,可通过重写initPropertySource设置环境变量
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
            // 初始化BeanFactory并进行xml文件读取
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            
             
			// Prepare the bean factory for use in this context.
    		// 对BeanFactory进行各种功能填充	
            prepareBeanFactory(beanFactory);

			try {
                // 空实现,可有子类实现,提供扩展能力
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

                // 激活各种BeanFactoryPostProcessors处理器
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

                // 注册BeanPostProcessors处理器
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
                
                // 国际化支持,初始化MessageSource
				// Initialize message source for this context.
				initMessageSource();

                // 初始化事件广播器,用于通知事件Listener 
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

                // 空实现,由子类实现
				// Initialize other special beans in specific context subclasses.
				onRefresh();

                // 查找所有注册的Listener,注册到广播器中
				// Check for listener beans and register them.
				registerListeners();

                // 初始化生下的单实例(非惰性)
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

                // 完成刷新过程,并触发ContextRefreshEvent事件通知,通知生命周期处理器刷新过程
				// Last step: publish corresponding event.
				finishRefresh();
			}

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

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

在refresh中逻辑还是很多的,根据代码块里添加了中文注释的地方逐步解释

在prepareRefresh中是做环境的准备的,环境变量的初始化以及系统属性的验证,可以通过实现initPropertySource方法进行环境变量的赋值操作等

protected void prepareRefresh() {
		// Initialize any placeholder property sources in the context environment.
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();
}

接下来就是加载BeanFactory了,前面已经知道默认是使用XmlBeanDefinitionReader来读取xml的

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

	@Override
	protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

实例化DefaultListableBeanFactory,XmlBeanFactory就是继承DefaultListableBeanFactory的;

在customizeBeanFactory中对BeanFactory进行了定制,设置是否允许覆盖同名对象以及是否允许循环依赖,并设置支持注解的解析器 QualifierAnnotaionAutowireCandidateResolver

在loadBeanDefinitions中就是比较熟悉的了,指定XmlBeanDefinitionReader为解析器,开始执行xml的解析了。

回到前面主流程中,接下来是对prepareBeanFacctory进行功能的填充

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
        // 设置表达式语言的解析器,提供对SPEL语言的支持
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        // 增加属性编辑器
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
        // 在bean初始化后,对实现Aware接口的实例提供一些资源
		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 interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
        // 注册依赖
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		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());
		}
	}

在setBeanExproeeionResolver中设置了SPEL支持的解析器,比如可以通过#{var}这种方式取值,在bean进行属性填充的时候,会通过这个解析器完成解析

在addPropertyEditorRegistrar中增加了属性注册编辑器,在ResourceEditorRegistrar中的registerCustomEditors中注册了一系列常用类型的属性编辑器;而ResourceEditorRegistrar是通过在AbstractBeanFactory中开始调用的,如下代码

	protected void initBeanWrapper(BeanWrapper bw) {
		bw.setConversionService(getConversionService());
		registerCustomEditors(bw);
	}
protected void registerCustomEditors(PropertyEditorRegistry registry) {
		PropertyEditorRegistrySupport registrySupport =
				(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
		if (registrySupport != null) {
			registrySupport.useConfigValueEditors();
		}
		if (!this.propertyEditorRegistrars.isEmpty()) {
			for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
				try {
                    // 遍历属性编辑器注册自定义编辑器
					registrar.registerCustomEditors(registry);
				}
				catch (BeanCreationException ex) {
					Throwable rootCause = ex.getMostSpecificCause();
					if (rootCause instanceof BeanCurrentlyInCreationException) {
						BeanCreationException bce = (BeanCreationException) rootCause;
						String bceBeanName = bce.getBeanName();
						if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {
							if (logger.isDebugEnabled()) {
								logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
										"] failed because it tried to obtain currently created bean '" +
										ex.getBeanName() + "': " + ex.getMessage());
							}
							onSuppressedException(ex);
							continue;
						}
					}
					throw ex;
				}
			}
		}
		if (!this.customEditors.isEmpty()) {
			this.customEditors.forEach((requiredType, editorClass) ->
					registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
		}
	}

接下来是addBeanPostProcessor,类ApplicationContextAwareProcessor实现了BeanPostProcessor接口,即会在bean实例化时候调用的,在postProcessBeforeInitialization中的invokeAwareInterfaces中,使实现了Aware接口的bean在被初始化之后可以取得一些资源

回到主流程,在功能填充后,即激活BeanFactoryPostProcessor,这个接口和BeanPostProcessor类似, BeanFactoryPostProcessor作用域范围是容器级的,允许在容器实际实例化任何其他的bean之前读取配置元数据。典型的应用是PropertyPlaceholderConfigure,在实例化bean之前会将 ${}格式进行变量替换。

注册BeanPostProcessor, 按照排序顺序进行注册,且重复注册情况会先移除在重新注册,保证beanPostProcessor的唯一性,在bean实例化阶段进行调用

在初始化消息 initMessageSource中,首先会查找已经定义的messageSource的bean,如果没有则使用默认的DelegationMessageSource并注册到beanFactory中

初始化事件广播器,和初始化消息差不多,去查找applicationEventMulticater的bean,否则使用默认的SimpleApplicationEventMulticater,在multicasstEvent中会遍历event的listener进行通知,观察者模式的典型应用。

初始化广播器后则是注册所有listener,来接收广播器的通知,即所有实现了ApplicationListener的bean

对于单例的bean(非lazy的),在ApplicationContext中会默认初始化,在preInstantiateSingletons中对单例的且非lazy的bean进行加载,即调用getBean方法。

在finishrefresh中,开始生命周期,通过实现Lifecycle接口,可以在生命周期开始时加载start方法,在最后会推送ContextRefreshEvent事件通知

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值