Spring IOC 循环依赖源码分析
一、分析前准备
(1)官网下载Spring源码
官网地址:https://github.com/spring-projects/spring-framework
(2)运行源码(idea)
-
在下载好的源码的根目录下运行cmd命令
gradlew :spring-oxm:compileTestJava
-
修改gradle下载镜像
repositories { mavenCentral() maven { url "http://maven.aliyun.com/nexus/content/groups/public/" } maven { url "https://maven.aliyun.com/repository/spring" } }
-
编译运行
(3)自建测试模块
-
Animal.java
package com.xunmeng.bean; import org.springframework.beans.factory.annotation.Autowired; public class Animal { private int age; private String name; @Autowired private Person person; public Animal(){} public Animal(String name,Integer age){ this.name=name; this.age=age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } }
-
Person.java
package com.xunmeng.bean; import org.springframework.beans.factory.annotation.Autowired; public class Person { private int age; private String name; @Autowired private Animal animal; public Person(){ } public Person(int age, String name) { this.age = age; this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String sayHello(){ return "hello:"+this.name; } public Animal getAnimal() { return animal; } public void setAnimal(Animal animal) { this.animal = animal; } }
-
SpringConfig.java
@Configuration public class SpringConfig { @Bean public Person person(){ return new Person(21,"Xunmeng"); } @Bean public Animal animal(){ return new Animal("Tom",5); } }
二、源码分析
1、public AnnotationConfigApplicationContext(Class<?>... componentClasses) {}
(1) this()
获取系统变量
演绎一下beanFactory工厂
设置一些依赖比较器 AnnotationAwareOrderComparator
设置一些依赖解析器 ContextAnnotationAutowireCandidateResolver
设置一些beanDefinition定义信息(不包括自己写的类)
设置一些过滤器、资源加载器
(2)register(componentClasses)
将配置类SpringConfig的bean定义信息放入到beanDefinitionMap中
(3) refresh()
其中有十二个方法
prepareRefresh(); 预准备刷新上下文
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();告诉子类去刷新内部的beanfactory ,获取刷新的bean factory 在用注解方式时在加载reader变量时就加载了DefaultListableBeanFactory
prepareBeanFactory(beanFactory); 预处理bean工场,注册一些系统bean对象
postProcessBeanFactory(beanFactory);留给之后开发者进行扩展
invokeBeanFactoryPostProcessors(beanFactory);将自定义配置类中的一些Bean加入bean定义信息map
registerBeanPostProcessors(beanFactory);注册拦截 bean 创建的 bean 处理器
initMessageSource();为此上下文初始化消息源
initApplicationEventMulticaster();为此上下文初始化事件多播器。
onRefresh();初始化特定上下文子类中的其他特殊 bean。
registerListeners();检查侦听器 bean 并注册它们
finishBeanFactoryInitialization(beanFactory);实例化所有剩余的(非懒加载初始化)单例。
- 分析图解:
finishRefresh();最后一步:发布相应的事件。