Spring 理念之 IOC
提到Spring,我们应该印象最深刻的就是IOC (Inversion of Control)
,即控制反转。
关于IOC,其实是一种设计理念,只是Spring将这个理念体现的淋漓尽致,所以一说到Spring,我们固然会很快的联想到IOC。IOC还有另外一个名字叫DI (Dependency Injection)
即依赖注入,其实,准确的来说,IOC是理念,那DI就是IOC的实现。
关于IOC更多详细理解可以看看这篇文章,IoC 之 2.1 IoC基础 ——跟我学Spring3
只要用过Spring,应该对Spring容器都不会陌生,这也是实现IOC的基础。在Spring中,我们所有的Bean实例都是交由Spring管理,包括Bean的实例化,初始化及销毁。Spring容器在启动时,会去扫描所有需要实例化的Bean,然后帮助我们去实例化,并且会自动将依赖的Bean同时实例化然后赋值,整个过程,我们完全不需要关心,而且Spring还提供了一系列用于我们自定义扩展的接口,如InitializingBean
,FactoryBean
,ApplicationContextAware
,BeanPostProcessor
等等。
Spring 容器介绍
关于Spring容器,我们可以重点关注两个接口:
- BeanFactory
这是最顶层的Spring容器的,它只定义了Spring容器的规范,更多的是面向Spring内部,一般我们不会直接去使用BeanFactory
。
在查看Spring源码的过程中就会发现,BeanFactory有很多的子接口以及实现类,最典型的如:DefaultListableBeanFactory
,该实现类一直贯穿着Spring容器的启动流程。
DefaultListableBeanFactory
继承关系如下:
从上图我们可以看出,DefaultListableBeanFactory
最终实现的最顶层的接口就是BeanFactory
,而BeanFactory
只定义了诸如BeanFactory#getBean()
等接口方法,所以Spring通过子接口以及抽象实现类的方式可以提供更全面的功能,如AbstractBeanFactory#createBean
用于创建实例化的Bean。
- ApplicationContext
ApplicationContext
其实也是Spring的容器,从字面意思可以理解为应用的上下文,也可以说是对BeanFactory
的扩展,因为ApplicationContext
不仅拥有BeanFactory的基本功能外,还提供了更多入口让我们接入Spring。ApplicationContext
还管理着Spring容器的生命周期,如容器的启动和关闭,并且还提供了更丰富的功能如事件发布监听,国际化等。
这里我们重点看一下GenericApplicationContext
,继承关系图如下:
在GenericApplicationContext
中会发现它持有一个DefaultListableBeanFactory
的引用,在Spring容器的启动流程中,就是利用DefaultListableBeanFactory
引入BeanFactory
中的所有功能。
Spring 容器启动
关于Spring容器的启动流程,其实大致包括以下几个步骤:
- 实例化
BeanFactory
,因为这是容器的基础,Spring中离不开BeanFactory
。 - 对
BeanFactory
做一些初始化,如添加一些默认的组件。 - 读取以及解析我们的配置类或者配置文件,然后将读取到的Bean封装到
BeanDefinition
缓存在一个beanDefinitionMap
中。 - 对解析到的
BeanDefition
进行实例化。 - 在实例化Bean的时候会执行Bean属性的填充,如依赖注入,然后做一些初始化,在初始化前后会执行Bean的拦截器。
了解完大致步骤,再从源码的角度去验证上面这些步骤,这里我使用的Java注解配置的,所以就从AnnotationConfigApplicationContext
开始:
实例化Spring容器,AnnotationConfigApplicationContext
:
在AnnotationConfigApplicationContext
的构造方法中,整个过程可以分为三步进行:
-
实例化
BeanFactory
从上面的类继承关系图可以看出,AnnotationConfigApplicationContext
间接继承了GenericApplicationContext
,所以最终会调用父类的构造方法:
在
GenericApplicationContext
的构造方法中直接new 了一个DefaultListableBeanFactory
。 -
注册基础的BeanPostProcessor
在AnnotationConfigApplicationContext
的无参构造中会去创建AnnotatedBeanDefinitionReader
:
由于
AnnotationConfigApplicationContext
继承自GenericApplicationContext
,而GenericApplicationContext
又实现了BeanDefinitionRegistry
,这样就拥有了注册BeanDefinition
的能力,所以在AnnotatedBeanDefinitionReader
实例化的时候会去注册一些基础的BeanFactoryPostProcessor
和BeanPostPorcessor
:public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); this.registry = registry; this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); // 注册基础的BeanFactoryPostProcessor和BeanPostPorcessor AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
此处具体的注册组件有:
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { // 将BeanDefinitionRegistry转换为DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { // 注解的排序 if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } // @Autowired 的解析器 if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); // 注册ConfigurationClassPostProcessor,用于后续解析配置类 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 注册AutowiredAnnotationBeanPostProcessor,用于Bean实例化后的依赖注入 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 注册CommonAnnotationBeanPostProcessor,用于@Resource注解的依赖注入 // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } ...... // 注册JPA的BeanPostProcessor // 注册EventListenerMethodProcessor // 注册DefaultEventListenerFactory return beanDefs; }
-
手工注册配置类
由于AnnotationConfigApplicationContext
注册Bean定义信息的能力,所以最终将当前我们指定的配置类注册到容器中:
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
容器启动
AbstractApplicationContext#refresh
是Spring容器启动的核心方法,该方法从整体上定义了Spring容器启动的整个流程,无论是SpringMVC,又或者Sping-boot,最终都会执行该方法去启动Spring容器:
public void refresh() throws BeansException, IllegalStateException {
......
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
......
}
按顺序查看每个方法的作用,大致如下:
prepareRefresh()
:容器刷新前的准备,如设置当前已经容器已经激活this.active.set(true)
。obtainFreshBeanFactory()
:获取当前上下文的BeanFactory实例,检查当前的refresh()
方法是否只被执行了一次,设置BeanFactory
的serializationId。prepareBeanFactory(beanFactory)
:获取ClassLoader
,设置基础的BeanPostProcessor
如:ApplicationContextAwareProcessor
,设置StandardBeanExpressionResolver
Spring EL表达式的解析器。设置某些接口的实现类不需要交由容器去实例化,如ApplicationContext
,因为ApplicationContext
在Spring启动时(第一步中)已经实例化完成不需要参与后续的Bean实例化过程。postProcessBeanFactory(beanFactory)
:AbstractApplicationContext
中定义的模板方法,可以重写实现注册一些额外的BeanPostProcessor。invokeBeanFactoryPostProcessors(beanFactory)
:执行BeanFactoryPostProcessor
,用于解析@Configuration
的配置类,如:扫描需要加载的Bean(@ComponentScan
),通过@Import
以及通过实现ImportBeanDefinitionRegistrar
加载对应的BeanDefinition
等。registerBeanPostProcessors(beanFactory)
:按照优先级去注册BeanPostProcessor
,通过调用AbstractBeanFactory#getBean
创建所有的BeanPostProcessor
的实例并缓存在BeanFactory
中,用于后续实例化其他Bean的时候做一些拦截处理,如:AOP生成代理对象。initMessageSource()
:初始化用于国际化的组件,这里不重点研究。initApplicationEventMulticaster()
:用于初始化Spring 事件的处理器。onRefresh()
:模板方法,用于子类实现。registerListeners()
:注册监听器。finishBeanFactoryInitialization(beanFactory)
:这是重点方法,开始实例化所有的单例Bean实例。- 容器刷新完毕后处理。
具体的执行源码由于篇幅原因拆分为多篇文章,可以按照下方的顺序:
- BeanFactory的实例化
obtainFreshBeanFactory()
:不同配置方式的BeanFactory实例化。 - BeanFactory的准备:
prepareBeanFactory(beanFactory)
:钩子方法的具体实现。 - 配置类的解析,
invokeBeanFactoryPostProcessors(beanFactory)
:手把手玩转 Spring 之 配置类解析ConfigurationClassPostProcessor - FactoryBean的创建
finishBeanFactoryInitialization(beanFactory)
手把手玩转 Spring 之 FactoryBean的创建 - 单例Bean的创建
- 单例Bean的初始化
- 基于Aware 接口的扩展:手把手玩转Spring 之 ApplicationContextAware