Spring源码
spring运行流程 ,最大的特点就是可扩展性
创建BeanDefinition对象
BeanDefinition接口:把配置文件定义的属性,分装成BeanDefinition对象并且填充占位符,不会自动去填充properties的值,放入到Container容器中。(利用loadBeanDefinitions(beanFactory),方法填充beandefinitionMap,和beandefinitionNames)。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
//准备相关上下文信息,设置标记位,设置时间,创建一些集合对象
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//获取BeanFactory工厂(DefltListableBeanFactory)。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//准备bean工厂一系列set,get方法。
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//Spring做了一些空方法,boot做了一些扩展和实现
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
//执行BeanFactoryPostProcessor放入BeanFactory中。boot自动装配的一些细节
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注册BeanPostProcessor并实例化
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
//国际化操作
initMessageSource();
// Initialize event multicaster for this context.
//多播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//boot的tomcat实现
onRefresh();
// Check for listener beans and register them.
//注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有非懒加载的实例对象,反射代码ctor.newinstance(); Bean的周期,实例化的操作都在这里实现。核心代码。
finishBeanFactoryInitialization(beanFactory);
// 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:成品对象
2:半成品对象
3:lambda表达式
2、如果只使用1级缓存行不行?
不行,因为成品和半成品对象会放到一起,在进行对象获取的时候有可能获取到半成品对象,这样的对象是没法使用的
3、如果只有二级缓存行不行?
getSingleton
doCreateBean
只有二级缓存的时候也可以解决循环依赖的问题,
添加aop的实现之后,报错,This means that said other beans do not use the final version of the bean.没有使用最终版本的bean对象
4、三级缓存存在到底做了什么事?
如果一个对象需要被代理,生成代理对象,那么这个对象需要预先生成非代理对象吗?需要
三级缓存到底做了什么?
lambda:getEarlyBeanReference(),只要搞清楚这个方法的具体执行逻辑即可
在当前方法中,有可能会用代理对象替换非代理对象,如果没有三级缓存的话,那么就无法得到代理对象,换句话说在整个容器中,包含了同名对象的代理对象和非代理对象,你觉得可以吗?
容器中,对象都是单例的,意味着根据名称只能获取一个对象的值,此时同时存在两个对象的话,使用的时候应该取哪一个?无法判断
谁也无法确认什么时候会调用当前对象,是在其他对缘的执行过程中来进行调用的,而不是人为指定的,所以必须要保证容器中任何时候都只有个对象供外部调用,所以在三级缓存中,完整了一件代理对象替换非代理对象的工作,确定返回的是唯一的对象。
三级缓存是为了解决在aop代理过程中产生的循环依赖问题,如果没有aop的话,二级缓存足矣解决循环依赖问题。
其实相当于是一个回调机制,当我都需要使用当前对象的时候,会判断此对象是否需要被代理实现,如果直接替换,不需要直接返回非代理对象即可。
5、spring是一个框架,跟业务完全无关,框架如何知道你什么时候用aop,什么时候不用aop呢?
但是在调用时候的时候,如果出现此问题怎么办呢?最重要的一件事,走总体的流程,如果有,就处理,没有就直接返回,不会有额外的任何影响。
第二步:填充占位符
在实例化对象的过程中使用 :PlaceholderConfigurerSupport实现BeanFactoryPostProcessor接口对BeanDefinition(转换成Bean对象时不会自动的填充属性值)的属性进行占位符填充,实现替换工作
第二步:自动装配(@注解)
spring中存在ConfigurationClassPostProcessorjava方法,底层分别去解析了所有的注解并进行处理,底层本质走的XML方式。
通过反射的方式进行对象的实例化
<1>创建对象