Spring 源码(一)Spring 容器的入口及简单介绍
Spring 容器的初始化
// 初始化容器
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
// 注册 Spring 内置后置处理器的 BeanDefinition 到容器
this();
// 注册配置类 BeanDefinition 到容器
register(annotatedClasses);
// 加载或者刷新容器中的Bean
refresh();
}
这个构造方法只有三行:
- 注册内置的BeanPostProcessor的BeanDefinition到容器
- 注册配置类 BeanDefinition 到容器
- 加载或者刷新容器中的Bean
容器的初始化过程我认为大致分为:
- 注册内置的BeanPostProcessor的BeanDefinition到容器
- 注册配置类 BeanDefinition 到容器
- 解析配置类
- 初始化所有单例Bean,并注册到容器
AnnotationConfigApplicationContext 总揽
我们来看下AnnotationConfigApplicationContext的类图:
(进入AnnotationConfigApplicationContext-> 在Idea类中右键 ->查看类图)
接下来我们来看具体Spring的相关结构
(类图使用技巧:右键某个接口或者类可对整个类图的相关类属性进行查看,很多时候源码没法看细节性的东西,粗略的看下类结构及方法即可)
AnnotationConfigApplicationContext说明- BeanFactory:它定义了Spring IOC容器最基本的功能规范,主要用来实例化、配置和管理Bean,它是IOC容器容器的心胀。主要包括bean获取,单例多例判断,Bean类型及别名获取
- HierarchicalBeanFactory:继承BeanFactory接口,新增了
getParentBeanFactory()方法,使BeanFactory具备了双亲IOC容器的管理功能。
- ListableBeanFactory:细化了许多BeanFactory接口的功能,比如
getBeanDefinitionNames()方法(获取容器中所有Bean定义的名称)。
- ResourceLoader:资源加载器。
- MessageSource:支持不同的信息源,从而实现国际化。
- ApplicationEventPublisher:支持应用事件,提供事件机制的定义。
- EnvironmentCapable:提供了对环境变量的支持。
- ApplicationContext:它继承了上述所有接口,是IOC容器的高级形态,它定了一个完成容器的雏形。(重点的类需要稍微记一下 方便后续进行回顾学习)
- AbstractApplicationContext:一个容器的抽象实现。
用户使用容器时,可以使用转义符"&"来得到FactoryBean本身,如果不加则是获取FactoryBean产生的对象。
BeanFactory和FactoryBean的区别
- BeanFactory:它是对IOC容器所有Bean进行管理,如实例化,配置和获取容器中的Bean。
- FactoryBean:它是一个能够生产或者修饰对象生成的工厂Bean。
BeanFactory :(通用bean处理)
BeanFactory 是基础类型的 IoC 容器,它由 org.springframework.beans.facytory.BeanFactory 接口定义,并提供了完整的 IoC 服务支持。简单来说,BeanFactory 就是一个管理 Bean 的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。
BeanFactory 接口有多个实现类,最常见的是 org.springframework.beans.factory.xml.XmlBeanFactory,它是根据 XML 配置文件中的定义装配 Bean 的。
创建 BeanFactory 实例时,需要提供 Spring 所管理容器的详细配置信息,这些信息通常采用 XML 文件形式管理。其加载配置信息的代码具体如下所示:
BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("D://applicationContext.xml"));
FactoryBean:(复杂自定义bean处理)
一般情况下,Spring通过反射机制利用2. FactoryBean的实现类 实现FactoryBean 实现其接口方法 重写getObject等其他bean方法
import org.springframework.beans.factory.FactoryBean;
public class FactoryBeanPojo implements FactoryBean{
private String type;
@Override
public Object getObject() throws Exception {
if("student".equals(type)){
return new Student();
}else{
return new School();
}
}
@Override
public Class getObjectType() {
return School.class;
}
@Override
public boolean isSingleton() {
return true;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
3.普通bean注册
public class School {
private String schoolName;
private String address;
private int studentNumber;
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
@Override
public String toString() {
return "School [schoolName=" + schoolName + ", address=" + address
+ ", studentNumber=" + studentNumber + "]";
}
}
public class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
4.测试
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.bean.FactoryBeanPojo;
public class FactoryBeanTest {
public static void main(String[] args){
String url = "com/spring/config/BeanConfig.xml";
ClassPathXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url);
//Bean工厂获取FactoryBean来获取bean
Object school= cpxa.getBean("factoryBeanPojo");
//获取自定义BeanFactory工厂 需要加&符号来标识
FactoryBeanPojo factoryBeanPojo= (FactoryBeanPojo) cpxa.getBean("&factoryBeanPojo");
System.out.println(school.getClass().getName());
System.out.println(factoryBeanPojo.getClass().getName());
}
}
结果:
com.spring.bean.Student com.spring.bean.FactoryBeanPojo
总结:BeanFacoty是SpringIOC容器的默认Bean管理,通过Factotybean可以自定义一些复杂的Bean
BeanFactory和ApplicationContext的区别
通过继承图我们可以发现
- BeanFactory是容器的基本定义。
- ApplicationContext继承自BeanFactory,是容器的高级形态,在BeanFactory的基础上添加了许多对高级容器特性的支持。
其次:
BeanFactory:
BeanFactory在启动的时候不会去实例化Bean,有从容器中拿Bean的时候才会去实例化;
ApplicationContext:
ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化