作为一名 Java 开发者,必须得学会 Spring 注解驱动开发。不然你将看不懂 Spring Boot、Spring Cloud 的底层实现原理?以及无法自主封装 Spring 组件?如何给已知的应用程序做功能拓展?学会 Spring 注解驱动开发,你的工作将会更加地轻松自如,升级加薪才会有希望。接下来,一起手把手完成 Spring 注解驱动开发的每一个场景案例(基本都是从实际工作中出发)!
本文主要内容:
- Spring 容器以及各个注解使用原理
- Spring 组件注册原理以及工作中的真实案例
- Spring 拓展原理,并实现应用功能拓展
前言
如果你之前一直在使用 Spring、Spring MVC 框架,那么一定需要编写大量的 xml 配置文件。如今,Spring Boot、Spring Cloud 兴起之后,其底层都是基于 Spring 注解驱动,使用大量的注解替代原先的 xml 配置文件,通过学习 Spring 注解驱动开发,了解每个注解的基本使用以及背后的原理,便于以后我们深入学习与使用 Spring Boot、Spring Cloud 框架。
前期准备工作
创建项目
next→next→finish→项目创建成功。
引入依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.25.RELEASE</version></dependency>
成功引入依赖:
容器
概述
Spring 之所以被广泛使用,是因为对于开发大型项目及其方便简单,这一切离不开 Spring 容器帮助我们管理 bean 的生命周期,那么 Spring 容器到底是什么呢?
bean 是 Spring 的的核心组成,而 Spring 容器就是用于管理这些对象的生命周期,例如:创建、销毁等。
项目中我们通过 ApplicationContext 的实现类来获取上下文,获取容器中的 bean 的元数据。
从代码上讲:一个 Spring 容器就是某个实现了 ApplicationContext 接口的类的实例。也就是说,从代码层面,Spring 容器其实就是一个 ApplicationContext(一个实例化对象)。
从源码角度来说,Spring 容器就是实现了 ApplicationContext 类的实例,获取当前环境的实例即可获取容器的内容,不同的项目环境上下文的实现类不同。
如:
# 实现 AbstractApplicationContext,xml 和注解都可以初始化 public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry # Spring Boot 中提供的实现,需要 Web Server 环境下使用 public class AnnotationConfigReactiveWebServerApplicationContext extends ReactiveWebServerApplicationContext implements AnnotationConfigRegistry
容器的功能
容器的分类及特点
容器的运行原理
创建方式
//创建基于注解的 springIOC 容器ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);//创建基于配置文件的 springIOC 容器ApplicationContext applicationContext = new ClassPathXmlApplicationContext(\"/spring-app.xml\");// 创建基于注解的 WebServer 环境的 springIOC 容器,等等。。。。。。。。。。。。。。。。ApplicationContext applicationContext = new AnnotationConfigServletWebServerApplicationContext();
运行原理
本文以 AnnotationConfigApplicationContext 为例,AnnotationConfigApplicationContext 构造器源码,用于初始化容器。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //1.会首先调用父类 GenericApplicationContext 中的构造方法,初始化工厂 bean 为 new DefaultListableBeanFactory() //2.调用自己的构造方法,初始化了一个读取器:AnnotatedBeanDefinitionReader reader;一个扫描器:ClassPathBeanDefinitionScanner scanner //3.在 reader 的初始化构造方法中,还注册了 6 个 post processors this(); //注册 bean,注册就是把 bean 都放在某个地方,一个并发 map 中,Map<String, BeanDefinition> beanDefinitionMap //这调用了 AnnotatedBeanDefinitionReader reader 的注册方法 //只注册了 6 个 post process 类 register(annotatedClasses); //实现的 bean 的初始化; //自定义的 bean 也在这里注册并初始化 refresh(); }
1. 注册容器 register()
源码解析:
public void register(Class<?>... annotatedClasses) { Assert.notEmpty(annotatedClasses, \"At least one annotated class must be specified\"); this.reader.register(annotatedClasses); }
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { //得到 bean 的描述信息,比如 bean 的注解,作用范围,是否懒加载,注入方式等 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); //被条件注解@Conditional 注释的 bean 跳过注册 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(instanceSupplier); //解析 bean 的 Scope,比如是否单例 singleton 还是其他 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); //生成 bean name,默认就是类名小写 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); //通过判断注解内容,设置一些公共属性,比如是否懒加载,优先级等 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)); } } } for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}
register 主要分为三步(只要是注册 BeanDefinition,都是这 3 步):
- 根据 class 文件获取 BeanDefinition,这里是其实现类 AnnotatedGenericBeanDefinition abd;
- 将 BeanDefinition 放到 BeanDefinitionHolder 中进一步封装;
- 最后一行,执行注册动作。
测试
随便一个普通的 Java 类进行注册到容器中:
public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(FistBeanFactoryPostProcessor.class); context.refresh(); FistBeanFactoryPostProcessor postProcessor = (FistBeanFactoryPostProcessor) context.getBean(\"fistBeanFactoryPostProcessor\"); System.out.println(null != postProcessor); }
通过断点调试,省略中间其它过程说明,直接上核心代码:
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, \"Bean name must not be empty\"); Assert.notNull(beanDefinition, \"BeanDefinition must not be null\"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, \"Validation of bean definition failed\", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info(\"Overriding user-defined bean definition for bean \'\" + beanName + \"\' with a framework-generated bean definition: replacing [\" + existingDefinition + \"] with [\" + beanDefinition + \"]\"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug(\"Overriding bean definition for bean \'\" + beanName + \"\' with a different definition: replacing [\" + existingDefinition + \"] with [\" + beanDefinition + \"]\"); } } else { if (logger.isTraceEnabled()) { logger.trace(\"Overriding bean definition for bean \'\" + beanName + \"\' with an equivalent definition: replacing [\" + existingDefinition + \"] with [\" + beanDefinition + \"]\"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
// 所有的 bean 注册最终都是 put beanDefinitionMap 中private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);// 注册的 bean nameprivate volatile List<String> beanDefinitionNames = new ArrayList<>(256);
2. 刷新容器 refresh()
AbstractApplicationContext 是 ApplicationContextspring IOC 容器的基类,refresh 方法是 Spring 最核心的方法,搞清楚这个方法的运行过程,拓展原理基本一看就会。
Spring 容器创建之后,会调用它的 refresh 方法刷新 Spring 应用的上下文。
Spring Boot 项目启动 run 中也是调用 refresh() 刷新上下文:
源码解析:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. //前期准备;记录了容器启动时间;容器状态;刷新一些在此方法之前就可能已经存在的监听器 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. //最终得到 DefaultListableBeanFactory,也就是在 this()方法中通过父类构造函数初始化的那个 bean factory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. //准备 bean factory,初始化工厂的一些标准固定的容器特性 //因为后边一系列容器初始化操作,都是基于 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. //实例化并执行之前已经注册了的各种 BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. //实例化 拦截 bean 创建的处理器 BeanPostProcessor; //这里的注册,是指把实例化的 BeanPostProcessor 存到 beanFactory 的某个 list 中 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. //初始化容器的 MessageSource 类型的 bean,MessageSource 用于解析消息 initMessageSource(); // Initialize event multicaster for this context. //初始化容器的事件广播 //用于管理若干 ApplicationListener 对象,并向他们推送消息 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. //空方法,在特定的子类中 初始化其他特殊 bean onRefresh(); // Check for listener beans and register them. //注册实现了 ApplicationListener 接口的监听者 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //实例化剩下的单例 bean,完成全部 bean 的实例化,除了懒加载的 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. //最后一步,完成此刷新方法,发布完成事件 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(); } }}
内部方法解析
总共分为 12 个重要过程,这里挑选重点解析。
1. prepareRefresh
protected void prepareRefresh() { // Switch to active. //容器启动时刻 this.startupDate = System.currentTimeMillis(); //容器激活状态,默认没有关闭 this.closed.set(false); //容器激活状态,默认激活的 this.active.set(true); if (logger.isInfoEnabled()) { logger.info(\"Refreshing \" + this); } // Initialize any placeholder property sources in the context environment. //空方法 initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Store pre-refresh ApplicationListeners... //执行 refresh 之前就已经注册的 listeners 集合,如果没有,就初始化集合; //调试发现是 null 的 if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. //如果不为空,重新设置到 applicationListeners 监听器集合 this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... //事件集合初始化 this.earlyApplicationEvents = new LinkedHashSet<>();}
2. invokeBeanFactoryPostProcessors(beanFactory)
实例化并执行之前已经注册了的各种 BeanFactoryPostProcessor,可用于拓展。
BeanFactoryPostProcessor 是 beanFactory 的后置处理器,也就是说当所有的 bean 定义已经保存并加载到 beanFactory,但是却没有被实例化。那么执行顺序:beanFactory > BeanFactoryPostProcessor > bean , 也就是说初始化完 beanFactory 之后 BeanFactoryPostProcessor 才会被调用,因此 BeanFactoryPostProcessor 是在 bean 初始化之后才会被调用,使用场景:用于定制或者修改 BeanFactory 的内容。
BeanFactoryPostProcessor 原理如下。
1. IOC 容器创建对象:
invokeBeanFactoryPostProcessors(beanFactory);
2. 先根据类型获取各种 postProcessorNames:
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
分类保存为各种 priorityOrderedPostProcessors、orderedPostProcessors、nonOrderedPostProcessors 的集合其实就是各种 BeanFactoryPostProcessor。
然后分别排序上一步的各种集合,按顺序分别执行各种 BeanFactory 的后置处理器。
案例:实现 BeanFactoryPostProcessor 接口。
public interface BeanFactoryPostProcessor { /** * Modify the application context\'s internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;}
public class FistBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { int beanDefinitionCount = beanFactory.getBeanDefinitionCount(); System.out.println(\"容器中的 bean 数量:\" + beanDefinitionCount); int beanPostProcessorCount = beanFactory.getBeanDefinitionCount(); System.out.println(\"beanPostProcessorCount:\" + beanPostProcessorCount); String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { System.out.println(\"beanDefinitionName:\" + beanName); } System.out.println(\"--------------------------BeanFactoryPostProcessor is after----------------------------------\"); } public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(FistBeanFactoryPostProcessor.class); String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { System.out.println(\"beanName:\" + beanName); } }}
输出结果:
3. postProcessBeanFactory(beanFactory)
空方法,用于子类扩展功能。
4. BeanDefinitionRegistryPostProcessor
- 在所有 bean 定义信息将要被加载,bean 实例还未创建的;
- 优先于 BeanFactoryPostProcessor 执行;
- 利用 BeanDefinitionRegistryPostProcessor 给容器中再额外添加一些组件。
5. BeanFactoryPostProcessor 原理
IOC 创建对象
refresh() -> invokeBeanFactoryPostProcessors(beanFactory);
从容器中获取到所有的 BeanDefinitionRegistryPostProcessor 组件。
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class ..);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
-> 依次触发所有的 postProcessBeanDefinitionRegistry() 方法 。
再来触发 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory)
-> postProcessBeanFactory() 方法 BeanFactoryPostProcessor。
之后从容器中找到 BeanFactoryPostProcessor 组件,然后依次触发 postProcessBeanFactory() 方法。
案例:
public class FistBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { System.out.println(\"FistBeanDefinitionRegistryPostProcessor...bean 的数量:\"+beanDefinitionRegistry.getBeanDefinitionCount()); RootBeanDefinition definition = new RootBeanDefinition(FistBeanFactoryPostProcessor.class); beanDefinitionRegistry.registerBeanDefinition(\"test\",definition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println(\"FistBeanDefinitionRegistryPostProcessor...bean 的数量:\"+configurableListableBeanFactory.getBeanDefinitionCount()); } public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(FistBeanDefinitionRegistryPostProcessor.class); String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { System.out.println(\"beanName:\" + beanName); } }}
6. registerListeners()
用于管理 ApplicationListener:
protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... //广播事件到对应的监听器; //earlyApplicationEvents 是在第一个方法 prepareRefresh()中初始化的 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } }}
7. finishBeanFactoryInitialization(beanFactory)
实例化所有的 bean,除了懒加载的 bean。
8. finishRefresh()
发布所有的事件:
protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. //执行 LifecycleProcessor 的方法 getLifecycleProcessor().onRefresh(); // Publish the final event. //发布完成事件给所有的监听者 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this);}
总结
源码执行过程详解
prepareRefresh 准备刷新容器
- initPropertySources() 自定义属性设置,空方法,留给子类继承。
- getEnvironment.validateRequiredProperties 首先获取环境配置,然后校验必需属性。
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
初始化事件监听器。this.earlyApplicationEvents = new LinkedHashSet<>();
初始化早期事件。
obtainFreshBeanFactory 获取组件工厂
- refreshBeanFactory 新建一个组件工厂,类型为 DefaultListableBeanFactory,然后对这个组件工厂设置了一个序列化 ID。
- getBeanFactory 返回刚刚创建的组件工厂。
prepareBeanFactory 对组件工厂做各种预处理设置
- 在组件工厂中设置类加载器、属性解析器等。
- 在组件工厂中添加部分组件后置处理器,例如 ApplicationContextAwareProcessor、ApplicationListenerDetector。
- 在组件工厂中设置忽略自动注入的接口。
- 设置自动装配规则。
- 在组件工厂中注册一些组件,例如环境配置 ConfigurableEnvironment。
postProcessBeanFactory 组件工厂的后置处理工作
invokeBeanFactoryPostProcessors 执行组件工厂后置处理器
这一步是在组件工厂的标准初始化(1~4)之后进行的,主要是执行 BeanFactoryPostProcessor 及其子接口的。
BeanFactoryPostProcessor 的子接口主要是指 BeanDefinitionRegistryPostProcessor,可以向容器中注册新的组件,这个接口的特点是有两个方法,一个是自身的 postProcessBeanDefinitionRegistry,另一个继承自 BeanFactoryPostProcessor 的 postProcessBeanFactory,从源码可以看出,Spring 会先执行 BeanDefinitionRegistryPostProcessor 类型的组件的自身方法,然后执行其继承方法,最后才调用非 BeanDefinitionRegistryPostProcessor 的 BeanFactoryPostProcessor 的后置处理方法。
- 从容器器中获取 BeanDefinitionRegistryPostProcessor 类型的组件。
- 将 BeanDefinitionRegistryPostProcessor 类型的组件按照顺序分类并排序,即是否实现了 PriorityOrdered、Ordered 接口。
- 依次执行实现了 PriorityOrdered 接口的、实现了 Ordered 接口的、没有实现任何顺序接口的组件的 postProcessBeanDefinitionRegistry 方法。
- 执行所有 BeanDefinitionRegistryPostProcessor 组件的 postProcessBeanFactory 方法。
- 从容器中获取其他的 BeanFactoryPostProcessor 类型的组件,即不是 BeanDefinitionRegistryPostProcessor 类型的。
- 剩下的步骤跟上面类似,就是先按照实现的顺序接口分类,在每个类别下排序,然后依次执行它们的 postProcessBeanFactory 方法。
registerBeanPostProcessors 注册组件后置处理器
这种处理器用于拦截 bean 的创建过程。beanPostProcessor 有很多子接口,每种子接口的执行时机各有不同。
- DestructionAwareBeanPostProcessor
- InstantiationAwareBeanPostProcessor
- MergedBeanDefinitionPostProcessor
- SmartInstantiationAwareBeanPostProcessor
1. 获取所有的 beanPostProcessor 的组件名。
2. 将所有的组件按优先顺序分为三类:
- 实现了 PriorityOrdered 接口的列表 priorityOrderedPostProcessors
- 实现了 Ordered 接口的列表 orderedPostProcessors
- 没有实现任何顺序接口的列表 nonOrderedPostProcessors
还有一种特殊情况,凡是 MergedBeanDefinitionPostProcessor 类型的,都放在 internalPostProcessors 中。
3. 注册 priorityOrderedPostProcessors。
4. 注册 orderedPostProcessors。
5. 注册 nonOrderedPostProcessors。
6. 注册 internalPostProcessors。
7. 注册 ApplicationListenerDetector,它的作用是在组件初始化之后判断其是否为 ApplicationListner 类型,如果是,则将其添加进容器的监听器集合。
initMessageSource 初始化消息源组件
用于消息绑定、消息解析等功能,并且提供国际化解决方案。
- 获取 beanFactory。
- 判断 beanFactory 中是否包含 id 为 messageSource 的组件。
- 如果已存在,则赋值给容器的 messageSource 属性,这种情况是我们自己在容器中注册了这个组件。
- 如果不存在,则新建一个 DelegatingMessageSource,并赋值给容器的 messageSource 属性,然后在 beanFactory 中注册这个新组件,并设置其 id 为 messageSource。
initApplicationEventMulticaster 初始化事件广播器
- 获取 beanFactory。
- 判断 beanFactory 中是否存在 id 为 applicationEventMulticaster 的组件
- 如果已存在,则赋值给容器的 applicationEventMulticaster 属性,这种情况是我们自己在容器中注册了这个组件。
- 如果不存在,则新建一个 SimpleApplicationEventMulticaster,并赋值给容器的 applicationEventMulticaster 属性,然后在 beanFactory 中注册这个新组件, 并设置其 id 为 applicationEventMulticaster。
onRefresh
留给子类继承的,我们可以自定义子容器,在重写方法中做一些我们想要的操作。
registerListeners 注册事件监听器
- 获取容器的属性 applicationListeners,这是一个事件监听器的集合,将集合中的每个元素都添加进事件广播器
getApplicationEventMulticaster().addApplicationListener(listener);
。 - 从容器中获取所有 ApplicationListener 类型的组件,将这些组件添加进事件广播器。
- 派发之前步骤产生的事件。
finishBeanFactoryInitialization 完成剩下的单实例 bean 的初始化
- 进入 DefaultListableBeanFactory.preInstantiateSingletons 方法,获取容器中所有的组件 id 列表。
- 获取容器中的所有 Bean,依次进行初始化和创建对象。
- Bean 不是抽象的,是单实例的,是非懒加载。
判断是否是 FactoryBean;是否是实现 FactoryBean 接口的 Bean;如果是就用工厂 bean 来创建及 FacBean 中的 getObject 同 SpringIOC 中的二(3)。如果不是工厂 Bean。利用 getBean(beanName) 创建对象。
getBean(beanName); ioc.getBean();
AbstractBeanFactory.doGetBean(name, null, null, false);
先获取缓存中保存的单实例 Bean。如果能获取到说明这个 Bean 之前被创建过(所有创建过的单实例 Bean 都会被缓存起来),Object sharedInstance = getSingleton(beanName);
缓存到 DefaultSingletonBeanRegistry 类的 singletonObjects 单例对象存储的 Map 一级缓存。
缓存中获取不到,开始 Bean 的创建对象流程。标记当前 bean 已经被创建:
markBeanAsCreated(beanName);
获取 Bean 的定义信息:
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName)
获取当前 Bean 依赖的其他 Bean,如果有按照 getBean(dep) 把依赖的 Bean 先创建出来:
String[] dependsOn = mbd.getDependsOn()
启动单实例 Bean 的创建流程如下:
AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args);
让 BeanPostProcessor 先拦截返回代理对象:
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
InstantiationAwareBeanPostProcessor 提前执行,先触发 postProcessBeforeInstantiation(),如果有返回值,触发 postProcessAfterInitialization()。
如果前面的 InstantiationAwareBeanPostProcessor 没有返回代理对象,调用 AbstractAutowireCapableBeanFactory.doCreateBean 创建 Bean。
创建 Bean 实例:
createBeanInstance(beanName, mbd, args);
利用工厂方法或者对象的构造器创建出 Bean 实例。
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用 MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition(mbd, beanType, beanName);
。
Bean 属性赋值:
populateBean(beanName, mbd, instanceWrapper);
拿到 InstantiationAwareBeanPostProcessor 后置处理器 postProcessAfterInstantiation(),拿到 InstantiationAwareBeanPostProcessor 后置处理器 postProcessPropertyValues()。
为 Bean 属性赋值,为属性利用 setter 方法等进行赋值:
applyPropertyValues(beanName, mbd, bw, pvs);
Bean 初始化:
initializeBean(beanName, exposedObject, mbd);
执行 Aware 接口方法:
invokeAwareMethods(beanName, bean);
执行 xxxAware 接口的方法 BeanNameAware\\BeanClassLoaderAware\\BeanFactoryAware。
执行后置处理器初始化之前:
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);BeanPostProcessor.postProcessBeforeInitialization();
执行初始化方法:
invokeInitMethods(beanName, wrappedBean, mbd);
是否是 InitializingBean 接口的实现,执行接口规定的初始化,是否自定义初始化方法。
执行后置处理器初始化之后,applyBeanPostProcessorsAfterInitialization 也就是 BeanPostProcessor.postProcessAfterInitialization()。
注册 Bean 的销毁方法:
registerDisposableBeanIfNecessary(beanName, bean, mbd);
将创建的 Bean 添加到缓存中 singletonObjects。
finishRefresh 完成容器刷新
- 初始化生命周期处理器(LifecycleProcessor),先从 BeanFactory 中按类型获取,如果没有就新建一个 DefaultLifecycleProcessor,并注册进 BeanFactory。
- 获取上一步注册的生命周期处理器,回调其 onRefresh 方法。
- 发布容器刷新事件,即 ContextRefreshedEvent。
流程图详解
简述
Spring 容器在启动的时候,先会保存所有注册进来的 Bean 的定义信息:
- xml 注册 bean:
<bean>
- 注解注册 Bean:@Service、@Component、@Bean、xxx
Spring 容器会合适的时机创建这些 Bean:
- 用到这个 bean 的时候,利用 getBean 创建 bean,创建好以后保存在容器中。
- 统一创建剩下所有的 bean 的时候 finishBeanFactoryInitialization()。
后置处理器 BeanPostProcessor
每一个 bean 创建完成,都会使用各种后置处理器进行处理,来增强 bean 的功能。
- AutowiredAnnotationBeanPostProcessor:处理自动注入
- AnnotationAwareAspectJAutoProxyCreator:来做 AOP 功能
- ….
- 增强的功能注解:AsyncAnnotationBeanPostProcessor
- ….
事件驱动模型
- ApplicationListener:事件监听
- ApplicationEventMulticaster:事件派发