文章目录
- 入口
- 起始
- new AnnotationConfigApplicationContext(Application.class);
- 配置类是否需要加 @Configuration
- super(); - GenericApplicationContext 的无参构造器
- this(); - AnnotationConfigApplicationContext 的无参构造器
- register(componentClasses); - AnnotationConfigApplicationContext 注册配置类的 BeanDefinition
- refresh(); - AbstractApplicationContext 的 refresh 方法
入口
AnnotationConfigApplicationContext 有多个构造函数, 还有两个成员属性, 分别是 AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner, 前者在初始化的时候会注册一些创世纪的处理器, 同时负责将配置类注册成为 BeanDefinition, 后者负责扫描类路径下的 Bean 候选者, 将其注册成为 BeanDefinition
AnnotationConfigApplicationContext()
AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory)
AnnotationConfigApplicationContext(Class<?>... componentClasses)
AnnotationConfigApplicationContext(String... basePackages)
我们常用的构造器是传入配置类的构造器, 实例化后调用 AnnotatedBeanDefinitionReader 的 register 方法将配置类注册成为 BeanDefinition, 然后调用 refresh 方法
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
另一个构造器是传入包路径的构造器, 实例化后调用 ClassPathBeanDefinitionScanner 的 scan 方法将类路径下的Bean候选者注册成为BeanDefinition, 然后调用 refresh 方法
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
AnnotationConfigApplicationContext 还提供了 register 和 scan 等方法用于主动注册和扫描注册 BeanDefinition 的方法, 其实现委托给了内部的 AnnotatedBeanDefinitionReader 和 ClassPathBeanDefinitionScanner
起始
@Configuration
public class Application {
@Bean
public String string() {
return "demo";
}
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Application.class);
Object bean = ac.getBean("string");
System.out.println(bean);
}
}
new AnnotationConfigApplicationContext(Application.class);
AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 子类在调用无参构造器时会调用父类的无参构造器, 即隐式调用 super(); 包括抽象类
// AnnotationConfigApplicationContext - GenericApplicationContext - AbstractApplicationContext - DefaultResourceLoader
// 调用父类 GenericApplicationContext 的无参构造器, 初始化了 beanFactory 为一个 DefaultListableBeanFactory
// 调用 AnnotationConfigApplicationContext 的无参构造器, 将 this 传入了 reader 和 scanner 的构造器, 初始化了 reader 和 scanner
// AnnotationConfigApplicationContext 也是一个 AnnotationConfigRegistry, 委托 DefaultListableBeanFactory 注册 BeanDefinition
this();
// 把 配置类(可多个) 注册成为 BeanDefinition, 为了在 refresh 中统一解析
// 加 @Configuration 的配置类被 Spring 称为 Full, 反之称为 Lite, Full 的在解析时会有额外的代理
register(componentClasses);
// 到这里, 注册了内部使用的类和配置类的 BeanDefinition
// Spring 中最重要的方法, 是一个模板方法, 该流程定义在 AbstractApplicationContext 中, 贯穿 Spring 应用的整个生命周期, 加载 bean 到销毁 bean
refresh();
}
配置类是否需要加 @Configuration
有 @Configuration注解, 标记为 FULL 配置类, 没有 @Configuration 注解, 但是存在 @Component, @ComponentScan, @Import, @ImportResource, 或者类中有 @Bean 注解标注的方法, 标记为 LITE 配置类, Full 配置类在解析时会做 CGLib 动态代理
配置类中的 @Bean 配置会受 @Configuration 有无的影响
没有 @Configuration 时, 在创建 Bean b 时, 会调用 b(), 在创建 Bean a 的时候还会再调用一次 b(), B 被实例化两次
配置 @Configuration 时, 调用 b() 会被 CGLib 动态代理加强, 会先从容器中获取, 有的话, 就不会再次调用了, 没有的话, 会创建并加入到容器中
@Bean
public B b() {
return new B();
}
@Bean
public A a() {
b();
return new A();
}
super(); - GenericApplicationContext 的无参构造器
创建了一个 DefaultListableBeanFactory
public GenericApplicationContext() {
// 创建了一个 DefaultListableBeanFactory, 是 BeanFactory 及其子接口的默认实现
// 注册 BeanDefinition, 创建和管理 Bean 都是该类完成的, 该类非常重要
this.beanFactory = new DefaultListableBeanFactory();
}
this(); - AnnotationConfigApplicationContext 的无参构造器
public AnnotationConfigApplicationContext() {
// AnnotatedBeanDefinitionReader 聚合了一个 BeanDefinitionRegistry, 由其代理注册/管理 BeanDefinition 的能力
// 根据继承实现关系可知, AnnotationConfigApplicationContext 也是一个 BeanDefinitionRegistry, 所以 this 可以直接作为入参传入
// AnnotatedBeanDefinitionReader 的主要作用是在容器启动早期, 把一些创世纪工具类(角色是基础设施)封装并注册为 BeanDefinition, 同时也提供了主动注册 BeanDefinition 的能力
// 调用传入的 BeanDefinitionRegistry 的注册 BeanDefinition 的能力, 传入的是一个 AnnotationConfigApplicationContext, 其注册 BeanDefinition 的能力是委托给其 beanFactory 属性的(DefaultListableBeanFactory)
this.reader = new AnnotatedBeanDefinitionReader(this);
// 提供 applicationContext.scan(basePackage) 主动调用能力
// 在解析配置类时使用的是该类的另一个实例对象
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
this.reader = new AnnotatedBeanDefinitionReader(this);
AnnotatedBeanDefinitionReader 的主要作用是在容器启动早期, 把一些创世纪工具类(角色是基础架构组件)封装并注册为 BeanDefinition, 主要包括如下工具类, 同时还负责代理 AnnotationConfigApplicationContext 的注册 BeanDefinition 的能力
- ConfigurationClassPostProcessor 该类非常重要, 用于解析配置类, 把相关类都注册成为 BeanDefinition, 只有该类是 BeanFactoryPostProcessor, 其他的都是 BeanPostProcessor
- AutowiredAnnotationBeanPostProcessor 解析 @Autowired
- CommonAnnotationBeanPostProcessor
- EventListenerMethodProcessor
- DefaultEventListenerFactory
- RequiredAnnotationBeanPostProcessor Spring 5.1 已经不再使用该工具类了
- PersistenceAnnotationBeanPostProcessor
创建 AnnotatedBeanDefinitionReader 对象, 最终会走到 AnnotationConfigUtils
// AnnotationConfigUtils.registerAnnotationConfigProcessors
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {
// 这里的 registry 其实是 AnnotationConfigApplicationContext 对象, 从中拿到 beanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
// ...
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 将 ConfigurationClassPostProcessor 注册成为 BeanDefinition
// ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor
// 拥有修改和注册 BeanDefinition 的能力, 负责解析配置类, 解析加了 @Configuration 的配置类, 解析 @ComponentScan, @ComponentScan 扫描的包, @Import 等, 将这些地方的相关 BeanDefinition 都注册到容器中
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 注册成为 BeanDefinition
// AutowiredAnnotationBeanPostProcessor 实现了 SmartInstantiationAwareBeanPostProcessor 和 InstantiationAwareBeanPostProcessor 和 MergedBeanDefinitionPostProcessor 和 BeanPostProcessor
// 解析 @Autowired, 在 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));
}
// 5.1 开始不注册 RequiredAnnotationBeanPostProcessor
// 解析 @Required, 是一个 BeanPostProcessor, 在 Bean 的属性注入的时候会用到
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
// 将 CommonAnnotationBeanPostProcessor 注册成为 BeanDefinition
// CommonAnnotationBeanPostProcessor 实现了 DestructionAwareBeanPostProcessor 和 MergedBeanDefinitionPostProcessor 和 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor
// 注意 CommonAnnotationBeanPostProcessor 继承自 InitDestroyAnnotationBeanPostProcessor
// 处理 @PostConstruct, @PreDestroy, @Resource, @WebServiceRef, @EJB 等注解
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));
}
// ...
// 将 EventListenerMethodProcessor 注册成为 BeanDefinition
// EventListenerMethodProcessor 实现了 BeanFactoryPostProcessor
// 可以从 BeanFactory 中拿到所有 EventListenerFactory 类型的 Bean, 排序后缓存起来备用
// 解析 @EventListener, spring 实现事件监听的方式有很多种, 其中一种就是在方法上添加 @EventListener 注解
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 将 DefaultEventListenerFactory 注册成为 BeanDefinition
// 解析 @EventListener
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
AnnotationConfigUtils.registerPostProcessor(registry, beanDefinition, beanName)
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
// ROLE_INFRASTRUCTURE, 表明当前 BeanDefinition 是基础架构组件, 是 Spring 内部使用的, 和用户无关的
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 调用 registry(即 AnnotationConfigApplicationContext) 注册 BeanDefinition
// 其实是 AnnotationConfigApplicationContext 代理了 DefaultListableBeanFactory 的所有 BeanDefinitionRegistry 能力
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
DefaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinition)
注册 BeanDefinition 其实是使用 AnnotationConfigApplicationContext 的父类 GenericApplicationContext 聚合的 DefaultListableBeanFactory 来实现的, 其内部维护了 BeanDefinitionMap 和 BeanDefinitionNames 两个容器, 用于存放 BeanDefinition 的信息, 注册就是把 BeanDefinition 添加到这两个容器中
// 在 启动注册 BeanDefinition 阶段
// 把 beanName 作为 key, BeanDefinition 作为 value, put 到 beanDefinitionMap 中
this.beanDefinitionMap.put(beanName, beanDefinition);
// 把 beanName add 到 beanDefinitionNames 中
this.beanDefinitionNames.add(beanName);
this.scanner = new ClassPathBeanDefinitionScanner(this);
实例化一个BeanDefinitionScanner, 只用于手动调用 applicationContext.scan(basePackage)
Spring Ioc 加载过程会用到该类的另一个实例来扫描
虽然类路径扫描非常快, 但通过在编译时创建候选的静态列表, 可以提高大型应用程序的启动性能. 在此模式下, 应用程序的所有模块都必须使用此机制, 当 ApplicationContext 检测到此类索引时, 它将自动使用它, 而不是扫描类路径. 启用方式就是 pom 中引入 spring-context-indexer 依赖, 这个过程将产生一个名为 META-INF/spring.components 的文件, 并将包含在jar包中. 如果在类路径中找到 META-INF/spring.components 时, 将自动启用索引. 也可以通过设置 spring.index.ignore 来配置是否启用索引
还有个非常重要的地方, new 的时候会调用 registerDefaultFilters(); 在里面注册扫描时过滤候选 component 的 includeFilters
ClassPathScanningCandidateComponentProvider.registerDefaultFilters();
默认会扫描的 Bean 候选, 包含有 @Component, @ManagedBean, @Named, 像 @Repository, @Service, @Controller 这类持有 @Component 元注解的注解也会被扫描到
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
ClassPathBeanDefinitionScanner.scan(String… basePackages)
扫描指定包的时候, 会从该包及所有子包中找到 满足包含在 includeFilters 且不包含在 excludeFilters 中的组件, 然后完善属性, 最终注册到 BeanDefinition 容器中
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 注册扫描到的 BeanDefinition
doScan(basePackages);
// Register annotation config processors, if necessary.
// Register annotation config processors, if necessary.
// 默认会像 AnnotatedBeanDefinitionReader 一样, 把创世纪类都注册成为 BeanDefinition
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
register(componentClasses); - AnnotationConfigApplicationContext 注册配置类的 BeanDefinition
委托给 reader把 配置类(可多个) 注册成为 BeanDefinition, 为了在 refresh 中统一解析
加 @Configuration 的配置类被 Spring 称为 Full, 反之称为 Lite, Full 的在解析时会有额外的代理
refresh(); - AbstractApplicationContext 的 refresh 方法
到这里, 注册了内部使用的类和配置类的 BeanDefinition
Spring 中最重要的方法, 是一个模板方法, 该流程定义在 AbstractApplicationContext 中, 贯穿 Spring 应用的整个生命周期, 从加载 bean 到销毁 bean
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备刷新上下文环境
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 获取 BeanFactory, 不同子类不同实现
// 这里拿到的是 GenericApplicationContext 的 beanFactory 属性, 即 DefaultListableBeanFactory, 实现了 BeanDefinitionRegistry
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 对 BeanFactory 进行属性填充
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 预留, 由子类实现
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// BeanFactoryPostProcessors 和 BeanDefinitionRegistryPostProcessor 主要的功能就是 注册和修改 BeanDefinition
// 这里将自动或手动注册的各种 BeanFactoryPostProcessors (包括 BeanDefinitionRegistryPostProcessor) 按一定的顺序规则逐个调用其 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法
// 当前阶段满足条件的只有解析配置类的工具类 ConfigurationClassPostProcessor, 所以 invokeBeanFactoryPostProcessors 方法可以认为就是在解析配置类
// 会从当前已注册的 BeanDefinition 中找到配置类, 把配置类本身, 配置类上面的 @PropertySource, @ComponentScan, @Component, @Import, @ImportResource 等注解都解析出来, 生成对应的 BeanDefinition 并注册到容器中
// 在这里会优先调用 getBean 来实例化实现了 BeanFactoryPostProcessor 的组件
// 如何判断一个 BeanDefinition 是一个配置类?
// - 有 @Configuration注解的 BeanDefinition, 标记为 FULL 配置类
// - 没有 @Configuration 注解, 但是有任一 @Component, @ComponentScan, @Import, @ImportResource 注解, 或者类中有 @Bean 注解标注的方法的 BeanDefinition, 标记为 LITE 配置类
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册 BeanPostProcessor
// 像处理 @Autowired 的 AutowiredAnnotationBeanPostProcessor 等, 必须在 Bean 实例化前准备好, 到时候才能正常工作
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化国际化资源处理器
initMessageSource();
// Initialize event multicaster for this context.
// 创建事件多播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 预留, 由子类实现. 一个空的回调, SpringBoot 就是在这里启动内置的 Web Servlet 容器
onRefresh();
// Check for listener beans and register them.
// 把事件监听器注册到事件多播器上
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 主要是实例化并注入属性并初始化所有剩余的满足条件的单例 Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 容器完成刷新, 发布刷新事件, SpringCloud 也是从这里启动的
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();
}
}
}