spring源码
环境搭建
maven依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
简单的一个Student类
package lean.bean;
public class Student {
String name;
int id;
public Student() {
System.out.println("Student被创建。。。。");
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
spring的配置文件:spring.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="stu1" class="lean.bean.Student"/>
</beans>
测试的main函数
package lean;
import lean.bean.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Student stu1 = context.getBean("stu1",Student.class);
System.out.println(stu1);
}
}
源码调用过程
废话不多说直接上spring ioc创建流程
ClassPathXmlApplicationContext 这个类是饿汉式加载的,即创建这个类的时候就会加载配置文件中的所有的bean。
下面是进入该类的构造器:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {
configLocation}, true, null);
}
从代码可以看出,构造器又调用了一个构造器,如下。
该构造器核心是
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent); //调用父对象进行初始化
setConfigLocations(configLocations);
if (refresh) {
//默认传入的是true,即直接加载bean
refresh(); //该函数是如何加载bean的核心
}
}
refresh()如下
在2处执行完之后,得到的beanFactory中的属性如下:其中的beanDefinitionMap中记录了从配置文件spring.xml中读取到的bean的配置信息。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); //1. 预处理
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //2. 得到一个beanFactory,用来创建bean,该步骤解析了spring.xml文件
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); //3. 预处理beanFactory
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // 4. beanFactory的后置处理器
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); //5. 注册后置处理器,注册spring自己用到的组件
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory); //6.注册拦截bean创建的bean处理器。
// Initialize message source for this context.
initMessageSource(); //7. 初始化消息源,国际化相关
// Initialize event multicaster for this context.
initApplicationEventMulticaster(); //8. 初始化事件转发器,因为在bean的生命周期可能有很多事件,因此需要事件转发器
// Initialize other special beans in specific context subclasses.
onRefresh(); //9. 初始化特定上下文子类中的其他特殊bean。一般留给子类创建
// Check for listener beans and register them.
registerListeners(); //10.注册监听器
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); //11.初始化非懒加载的bean,所有的bean都是单例模式
// 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();
}
}
}
上面的第11步骤是初始化所有单实例bean的函数,如下:
该函数是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 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));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassL/oader(null); //设置临时的类加载器
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration(); //冻结配置,不希望修改
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons(); //!!**预初始化所有单实例**
}
preInstantiateSingletons函数如下,该函数是DefaultListableBeanFactory类的方法。注意,又是一个bean工厂
@Override
public void preInstantiateSingletons() throws BeansException {
// 看到logger可以跳过了,哈哈,因为是一些日志记录,无关紧要
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); // 获取到需要创建的所有bean的name
// Trigger initialization of all non-lazy singleton beans...
// 按照顺序创建bean
for (String beanName : beanNames) {
// 拿到bean的定义,该定义是从xml配置文件中读取到的 beanName即为bean中定义的id
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 当bean不是抽象的且是单例的且不是懒加载的才创建
if (!bd.isAbstract() && bd/.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {