了解专栏完整的内容,请点击跳转:
Spring Framework专栏导航页
为了阐述得简要些,以下几篇内容都侧重于介绍注解方式的Spring容器,XML方式的略过。
什么是Spring容器
微观来说这个容器就是存储bean的Map,宏观来说(一般来说)是指ApplicationContext或者Spring框架的概念。
我们知道Spring是基于Ioc原理来管理我们的bean,让程序员解放双手,使对象的创建和使用不再犯难。
所以,Spring在启动的时候,会把我们用注解标识的bean都创建好并存起来,这个存的地方就是我们所说的容器,Spring的容器是用 Map<String, Object>
结构来存我们的bean,为了解决bean之间创建时候可能有循环依赖
问题,所以又加了两个Map结构,一共三个:
- Map<String, Object> singletonObjects // 一级缓存,存放的是已完全创建完的bean
- Map<String, Object> earlySingletonObjects // 二级缓存,存放的是已实例化但未进行属性赋值和初始化的bean
- Map<String, ObjectFactory<?>> singletonFactories // 三级缓存,存放的value是一个函数接口 通过getObject获得bean
什么是BeanFactory
Spring有了容器,那就解决了存放的问题,那这么多奇奇怪怪的bean又该怎么创建呢?
Spring使用了简单工厂
的设计模式,即用BeanFactory来生产我们的bean
什么是FactoryBean
他其实也是一种工厂,看一下这个接口就知道了。
最重要的就是getObject,可以拿到一个bean,和beanFactory功能一样。
可以供其他框架整合时候作为一个衔接纽带。
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
什么是ApplicationContext
是一种特殊的BeanFactory,功能比BeanFactory强大
像Springboot
启动类:
ConfigurableApplicationContext contxt = SpringApplication.run(Application.class, args)
还有AnnotationConfigApplicationContext
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MainConfig.class);
回归正题
好了,铺垫了一些概念,现在回到正题,Spring究竟是如何初始化的。
流程图如下:
Spring容器初始化
源码
从这里开始
public class Application {
public static void main(String[] args) {
// 注解配置方式的spring容器 启动时候能完成单例bean的生产 供项目使用
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
MainConfig bean = context.getBean(MainConfig.class);
System.out.println(bean);
}
}
AnnotationConfigApplicationContext 构造器
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 空参构造函数 (实例化bean工厂、创建bean定义读取器、创建bean定义扫描器)
this();
// 注册配置类(即自定义的配置类)到bean定义Map中
register(componentClasses);
// ioc容器刷新接口 这个是最重要的 前面都是准备工作 还没有一个bean完成创建
refresh();
}
空参构造函数
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 创建bean定义读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
//创建BeanDefinition扫描器
// 这个扫描器是给程序员手动调用扫描器的 解析@ComponentScan时候,会再创建一个扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
AnnotatedBeanDefinitionReader核心代码
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
//把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
this.registry = registry;
//用于处理条件注解 @Conditional
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//注册一些内置的后置处理器 用于解析@Component、@Configuration等
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
注册配置类
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
// 这里跟进去
this.reader.register(componentClasses);
registerComponentClass.end();
}
配置类注册的核心代码
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//存储@Configuration注解注释的类
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//判断是否需要跳过注解,spring中有一个@Condition注解,当不满足条件,这个bean就不会被解析
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
//解析bean的作用域,如果没有设置的话,默认为单例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
//获得beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解为Lazy,Primary,DependsOn,Role,Description
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
BeanDefinitionHolder definitionHolder =