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;
}