Spring源码阅读(一)

Spring源码阅读,我们直接用idea,maven,然后通过Spring最基本的xmlApplicationContext进行xml加载获取bean的形式进行处理,通过断点执行,进行源码的阅读。本文需要一定的Spring编程经验,内容都是博主理解和整理的,如有问题请指出。

0、准备阶段

首先构建项目,用最原始的方法使用Spring。

目录
在这里插入图片描述
User

package com.yin.demo.bean;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.Setter;

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Setter
public class User {
    String name;
    public void show(){
        System.out.println("_______________________");
    }
}

TClass

package com.yin.demo;

import com.yin.demo.bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TClass {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        User user = applicationContext.getBean(User.class);
        user.show();
    }
}

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 配置使用额外的properties -->
    <context:property-placeholder file-encoding="UTF-8" location="classpath:/test.properties"/>

    <bean name="user" class="com.yin.demo.bean.User">
        <property name="name" value="${name}"/>
    </bean>
</beans>

test.properties

name=yinjiacheng

在启动类上打上断点。
在这里插入图片描述

1、运行

Debug运行TClass.java,F7进入方法下一步查看,F8不进入方法下一步查看,ctrl+alt+左跳回前一次光标位置,ctrl+alt+左跳回后一次光标外置。走起。

1.1 进入到ClassPathXmlApplicationContext的构造方法

在这里插入图片描述
在这里插入图片描述
parent:父类实例,这里我们传入的是null
setConfigLocations(@Nullable String… locations):传入xml的地址
refresh():Spring容器的核心的方法,也是我们主要研究的方法,实现了容器的更新,包括第一次启动

1.2 进入到AbstractApplicationContext规范的refresh()方法

这里提一下,看名字AbstractApplicationContext是一个抽象类,refresh中的方法都在AbstractApplicationContext直接实现了。我们先简单总体介绍一下各个函数的作用,这里我把官方的英文注释也留着,方便对比查看。

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) { // Monitor,专门定义的用来开和关Spring容器过程的一个上锁,就是一个简单的new Object();
			// Spring后面的版本加进来的,一些启动参数
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			/**
			 * 刷新上下文环境
			 * 初始化上下文环境,对系统的环境变量或者系统属性进行准备和校验
			 * 如环境变量中必须设置某个值才能运行,否则不能运行,这个时候可以在这里加这个校验,
			 * 重写initPropertySources方法就好了
			 */
			// Prepare this context for refreshing.
			prepareRefresh();

			/**
			 * 获取一个最新的beanFactory,如果第一次,就初始化BeanFactory
			 */
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			/**
			 * 之前创建的beanFactory的很多属性都还是空值或者0,这里对于其值进行一个赋值
			 * 为上下文准备BeanFactory,即对BeanFactory的各种功能进行填充,如常用的注解@Autowired @Qualifier等
			 * 设置SPEL表达式#{key}的解析器
			 * 设置资源编辑注册器,如PerpertyEditorSupper的支持
			 * 添加ApplicationContextAwareProcessor处理器
			 * 在依赖注入忽略实现*Aware的接口,如EnvironmentAware、ApplicationEventPublisherAware等
			 * 注册依赖,如一个bean的属性中含有ApplicationEventPublisher(beanFactory),则会将beanFactory的实例注入进去
			 */
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				/**
				 * 提供子类覆盖的额外处理,即子类处理自定义的BeanFactoryPostProcess, AbstractApplicationContext类中对其实现是个空函数
				 */
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// beanPostProcess 启动的一些信息
				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");

				/**
				 * 激活各种BeanFactory处理器,包括BeanDefinitionRegistryBeanFactoryPostProcessor和普通的BeanFactoryPostProcessor
				 * 执行对应的postProcessBeanDefinitionRegistry方法 和  postProcessBeanFactory方法
				 */
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				/**
				 * 注册拦截Bean创建的Bean处理器,即注册BeanPostProcessor
				 * 这里仅仅是注册,并不会执行对应的方法,将在bean的实例化时执行对应的方法
				 */
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				// 隔离操作,当已经end之后,不能再注册beanPostProcessor
				beanPostProcess.end();
				
				/**
				 * 初始化上下文中的资源文件,如国际化文件的处理等
				 */
				// Initialize message source for this context.
				initMessageSource();

				/**
				 * 初始化上下文事件广播器,并放入applicatioEventMulticaster,如ApplicationEventPublisher
				 */
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				/**
				 * 给子类扩展初始化其他Bean
				 */
				// Initialize other special beans in specific context subclasses.
				onRefresh();

				/**
				 * 在所有bean中查找listener bean,然后注册到广播器中
				 */
				// Check for listener beans and register them.
				registerListeners();

				/**
				 * 设置转换器
				 * 注册一个默认的属性值解析器
				 * 冻结所有的bean定义,说明注册的bean定义将不能被修改或进一步的处理
				 * 初始化剩余的非惰性的bean,即初始化非延迟加载的bean
				 */
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				/**
				 * 初始化生命周期处理器DefaultLifecycleProcessor,DefaultLifecycleProcessor含有start方法和stop方法,spring启动的时候调用start方法开始生命周期,
				 * spring关闭的时候调用stop方法来结束生命周期,通常用来配置后台程序,启动有一直运行,如一直轮询kafka
				 * 启动所有实现了Lifecycle接口的类
				 * 通过spring的事件发布机制发布ContextRefreshedEvent事件,以保证对应的监听器做进一步的处理,即对那种在spring启动后需要处理的一些类,这些类实现了
				 * ApplicationListener<ContextRefreshedEvent> ,这里就是要触发这些类的执行(执行onApplicationEvent方法)另外,spring的内置Event有ContextClosedEvent、ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent、RequestHandleEvent
				 * 完成初始化,通知生命周期处理器lifeCycleProcessor刷新过程,同时发出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();
				contextRefresh.end();
			}
		}
	}

1.3 finishBeanFactoryInitialization,bean的初始创建过程

上面已经描述了AbstractApplicationContext中refresh方法里面的内容,可以debug一步步往里面走,查看其大致流程,下面具体介绍finishBeanFactoryInitialization()方法。

该方法会实例化所有剩余的非懒加载单例 bean。除了一些内部的 bean、实现了 BeanFactoryPostProcessor 接口的 bean、实现了 BeanPostProcessor 接口的 bean,其他的非懒加载单例 bean 都会在这个方法中被实例化,并且 BeanPostProcessor 的触发也是在这个方法中。

AbstractApplicationContext


	/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		// 初始化上下文的转换服务
		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));
		}

		// Register a default embedded value resolver if no BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		// 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		// 初始化LoadTimeWeaverAware Bean实例对象
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		// 冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,马上要创建 Bean 实例对象了
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// 实例化所有剩余(非懒加载)单例对象
		beanFactory.preInstantiateSingletons();
	}

1.4 preInstantiateSingletons() 方法说明

这是DefaultListableBeanFactory类中的方法。DefaultListableBeanFactory其实要实现的功能就是以list集合的方式操作bean。

在这里插入图片描述

@Override
	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.
		// 获取beanDefinitionName的List用于之后的遍历
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 初始化左右非懒加载的bean对象
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 如果bean不是抽象的,且是单例的,且没有懒加载
				if (isFactoryBean(beanName)) {
					// 如果是factoryBean
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						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是能够得到这个bean的,是都返回值的。但同时,如果这个beanName是第一次加载,就会进行装配。所以在这里我们的目的是为了将bean创建出来。
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		// 触发 post-initialization 的回调
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

1.5 doGetBean

从上面的方法中,找到核心的方法是getBean,禁去之后发现调用了AbstractBeanFactory的doGetBean方法,下面对其进行进一步研究

AbstractBeanFactory

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * @param name the name of the bean to retrieve
	 * @param requiredType the required type of the bean to retrieve
	 * @param args arguments to use when creating a bean instance using explicit arguments
	 * (only applied when creating a new instance as opposed to retrieving an existing one)
	 * @param typeCheckOnly whether the instance is obtained for a type check,
	 * not for actual use
	 * @return an instance of the bean
	 * @throws BeansException if the bean could not be created
	 */
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
			
		//1.根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
		//2.如果指定的是别名,将别名转换为规范的Bean名称
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// Eagerly check singleton cache for manually registered singletons.
		// 这里先尝试从缓存中获取,获取不到再走后面创建的流程。
		// 获取到有两种情况,一种是Bean创建完成存储到最终的缓存中。
		// 另一种是未创建完成,但先预存到一个单独的缓存中,这种是针对可能存在循环引用的情况的处理。
		Object sharedInstance = getSingleton(beanName);
		// 如果已经能从cache中取到这个bean了
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				// 循环依赖导致的,正在被另一个线程创建
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				// 直接从cached中拿到了这个bean
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			// 根据其实bean还是factoryBean进行不同的处理
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
	
		// 否则就是说明这个bean还未被实例化过,所以需要创建这个bean
		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			// 原型对象不允许循环创建,如果是原型对象则抛异常;另外包括构造器实例化也不能循环依赖,会在另一个位置报异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			// 如果存在父容器,且Bean在父容器中有定义,则通过父容器返回
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
			// 将bean标记成已创建
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
				// 根据名字获取合并过的对应的RootBeanDefinition
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 检查mbd是否为抽象的或mbd为单例,但存在args的情况(args只有初始化原型对象才允许存在)
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				// 确保当前Bean依赖的相关Bean先完成初始化工作
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				// 前面获取失败,开始创建
				if (mbd.isSingleton()) {
					// 会先尝试从缓存中获取,获取失败就通过ObjectFactory的createBean方法创建
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 创建单例对象
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					//这里主要处理实现了FactoryBean的情况,需要调用重写的getObject()方法来获取实际的Bean实例。
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				// 如果是原型对象
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						// 将正在创建的原型对象进行记录
						beforePrototypeCreation(beanName);
						// 创建原型对象
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						// 移除正在创建的原型对象记录
						afterPrototypeCreation(beanName);
					}
					//处理FactoryBean,需要调用重写的getObject()方法来获取实际的Bean实例。
					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
				beanCreation.end();
			}
		}
		// 检查是否为要求的类型,如果不是则尝试进行类型转换,spring 5对其进行的封装
		return adaptBeanInstance(name, beanInstance, requiredType);
	}

1.6 getSingleton方法从cache中获取bean对象

这里就是三级缓存的主要内容了,DefaultSingletonBeanRegistry类中的发方法

/**
	 * Return the (raw) singleton object registered under the given name.
	 * <p>Checks already instantiated singletons and also allows for an early
	 * reference to a currently created singleton (resolving a circular reference).
	 * @param beanName the name of the bean to look for
	 * @param allowEarlyReference whether early references should be created or not
	 * @return the registered singleton object, or {@code null} if none found
	 */
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		// 如果这个单例bean已经生产,切放在singletonObjects中,就可以直接从这个一级缓存中取到。
		Object singletonObject = this.singletonObjects.get(beanName);
		// 如果一级缓存中没有取到,同时这个bean有没有同时在被创建
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			// 如果是空的,同时允许从二级缓存中寻找,就继续操作
			if (singletonObject == null && allowEarlyReference) {
				// 现在我们在处理这个bean对象了,处理完后会放到singletonObjects中,所以我们要讲一级缓存先锁住,然后进行处理
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						// 从二级缓存中寻找,二级缓存是还未初始化的bean对象
						singletonObject = this.earlySingletonObjects.get(beanName);
						// 如果也没有取到,就要从三级缓存工厂中创建一个bean
						if (singletonObject == null) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								// 创建完后,就放到二级缓存中
								this.earlySingletonObjects.put(beanName, singletonObject);
								// 然后从三级缓存中去掉
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cofer_Yin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值