Spring注解开发_Spring容器创建概述
浅尝Spring注解开发_Spring容器创建概述
浅尝Spring注解开发,基于Spring 4.3.12
概述Spring容器创建的过程,包括12个方法的执行
浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配
浅尝Spring注解开发_Bean生命周期及执行过程
浅尝Spring注解开发_AOP原理及完整过程分析(源码)
浅尝Spring注解开发_声明式事务及原理
浅尝Spring注解开发_简单理解BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor、ApplicationListener
Spring注解开发_Spring容器创建概述
概述12个方法
	//获取ioc容器
	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
	/**
	 * 创建一个新的AnnotationConfigApplicationContext,派生bean定义
	 * 从给定的带注释的类,并自动刷新上下文。
	 * @param 类一个或多个带注释的类
	 * e.g. {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		this();
		register(annotatedClasses);
		refresh();
	}
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 为刷新准备此上下文。
			prepareRefresh();
			// 告诉子类刷新内部bean工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			// 准备在此上下文中使用bean工厂。
			prepareBeanFactory(beanFactory);
			try {
				// 允许在上下文子类中对bean工厂进行后处理。
				postProcessBeanFactory(beanFactory);
				// 调用在上下文中注册为bean的工厂处理器。
				invokeBeanFactoryPostProcessors(beanFactory);
				// 注册拦截bean创建的bean处理器。
				registerBeanPostProcessors(beanFactory);
				// 初始化此上下文的消息源。
				initMessageSource();
				// 为此上下文初始化事件多播。
				initApplicationEventMulticaster();
				// 在特定的上下文子类中初始化其他特殊bean。
				onRefresh();
				// 检查监听器bean并注册它们。
				registerListeners();
				// 实例化所有剩余的(非lazy-init)单例。
				finishBeanFactoryInitialization(beanFactory);
				// 最后一步:发布相应的事件。
				finishRefresh();
			}
        	//...
BeanFactory预处理
BeanFactory的创建及预准备工作
- BeanFactory 的作用是负责 bean 的创建、依赖注入和初始化,bean 的各项特征由 BeanDefinition 定义
 - BeanDefinition 作为 bean 的设计蓝图,规定了 bean 的特征,如单例多例、依赖关系、初始销毁方法等
 - BeanDefinition 的来源有多种多样,可以是通过 xml 获得、配置类获得、组件扫描获得,也可以是编程添加
 - 所有的 BeanDefinition 会存入 BeanFactory 中的 beanDefinitionMap 集合
 
1、this()
- 先调用父类构造器
 - 声明两个类,通过读取注解或者扫描类路径读取
BeanDefinition - 初始化了DefaultListableBeanFactory:基于bean定义元数据的成熟bean工厂,可通过后处理器进行扩展,内部定义了 
BeanDefinition的Map属性名beanDefinitionMap,可以操作bean - 注册了多个(6个)默认的后置处理器
 
2、register(annotatedClasses)
- 校验传入的 
JavaConfig.class配置类的注解(是否需要忽略) - 处理通用注解
 - 封装为
BeanDefinitionHolder后,注册到容器中 - 相当于将JavaConfig配置类作为一个Bean注册到容器中
 
3、Spring容器的refresh():创建刷新
prepareRefresh():刷新前的预处理initPropertySources()[初始化属性源]:初始化一些属性设置,空方法,留给子类自定义个性化的属性设置方法getEnvironment().validateRequiredProperties():检验属性的合法等earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>():保存容器中的一些早期的事件,一旦多播机可用就会发布
obtainFreshBeanFactory()(//告诉子类刷新内部Bean工厂):获取新鲜的BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()类注释://大多数可列出的bean工厂要实现的配置接口。 除了 {@link ConfigurableBeanFactory} 之外,它还提供了以下工具: 分析和修改 bean 定义,并预实例化单例。refreshBeanFactory():刷新[创建]BeanFactory- 创建了一个
this.beanFactory = new DefaultListableBeanFactory()。补充:这个方法在创建AnnotationConfigApplicationContext的父类GenericApplicationContext的无参构造时调用了,注释是//创建一个新的 GenericApplicationContext - 设置id
 
- 创建了一个
 getBeanFactory():返回刚才GenericApplicationContext创建的BeanFactory对象- 将创建的
BeanFactory[类型:DefaultListableBeanFactory]返回 
prepareBeanFactory(beanFactory):BeanFactory的预准备工作(BeanFactory进行一些设置)- 设置
BeanFactory的类加载器、支持表达式解析器... - 添加部分
BeanPostProcessor[类型:ApplicationContextAwareProcessor] - 设置忽略的自动装配的接口
EnvironmentAware、EmbeddedValueResolverAware、xxx... - 注册可以解析的自动装配;我们能直接在任何组件中自动注入:
BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext... - 添加
BeanPostProcessor[类型:ApplicationListenerDetector],将用于检测内部 bean 的早期后处理器注册为ApplicationListener - 添加编译时的
AspectJ - 给
BeanFactory中注册一些能用的组件;ConfigurableEnvironment environment:application上下文环境Map<String, Object> systemProperties:系统属性Map<String, Object> systemEnvironment:系统环境变量
 
- 设置
 postProcessBeanFactory(beanFactory):BeanFactory准备工作完成后进行的后置处理工作- 子类通过重写这个方法来在
BeanFactory创建并预准备完成以后做进一步的设置 
- 子类通过重写这个方法来在
 
执行BeanFactoryPostProcessor
BeanFactoryPostProcessor是beanFactory的后置处理器
BeanFactoryPostProcessor是beanFactory的后置处理器,在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
执行BeanFactoryPostProcessor分两步,先执行BeanDefinitionRegistryPostProcessor,后执行BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor的方法。BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化(以上4步)之后执行的,两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor执行
BeanFactoryPostProcessor的方法先执行
BeanDefinitionRegistryPostProcessor获取所有的
BeanDefinitionRegistryPostProcessor看先执行实现了
PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessorpostProcessor.postProcessBeanDefinitionRegistry(registry)再执行实现了
Ordered顺序接口的BeanDefinitionRegistryPostProcessorpostProcessor.postProcessBeanDefinitionRegistry(registry)最后执行没有实现任何优先级或者是顺序接口的
BeanDefinitionRegistryPostProcessorspostProcessor.postProcessBeanDefinitionRegistry(registry)
再执行
BeanFactoryPostProcessor的方法获取所有的
BeanFactoryPostProcessor看先执行实现了
PriorityOrdered优先级接口的BeanFactoryPostProcessorpostProcessor.postProcessBeanFactory()再执行实现了
Ordered顺序接口的BeanFactoryPostProcessorpostProcessor.postProcessBeanFactory()最后执行没有实现任何优先级或者是顺序接口的
BeanFactoryPostProcessorpostProcessor.postProcessBeanFactory()
注册BeanPostProcessor
按照优先级注册后置处理器,不执行
registerBeanPostProcessors(beanFactory):注册BeanPostProcessor(Bean的后置处理器)拦截Bean的创建不同接口类型的
BeanPostProcessor,在Bean创建前后的执行时机是不一样的BeanPostProcessor后置处理器DestructionAwareBeanPostProcessor销毁感知后置处理器InstantiationAwareBeanPostProcessor实例化感知后置处理器SmartInstantiationAwareBeanPostProcessor智能实例化感知后置处理器MergedBeanDefinitionPostProcessor[internalPostProcessors]合并Bean定义信息后置处理器
获取所有的
BeanPostProcessor,后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级先注册
PriorityOrdered优先级接口的BeanPostProcessor把每一个
BeanPostProcessor添加到BeanFactory中,beanFactory.addBeanPostProcessor(postProcessor)再注册
Ordered接口的最后注册没有实现任何优先级接口的
最终注册
MergedBeanDefinitionPostProcessor注册一个
ApplicationListenerDetector,来在Bean创建完成后检查是否是ApplicationListener,如果是就添加组件applicationContext.addApplicationListener((ApplicationListener<?>) bean)
初始化MessageSource
国际化
initMessageSource():初始化MessageSource组件(做国际化功能;消息绑定,消息解析)获取
BeanFactory看容器中是否有id为
messageSource的,类型是MessageSource的组件,如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSourceMessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取把创建好的
MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSourcebeanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale)
初始化事件派发器、监听器
initApplicationEventMulticaster():初始化事件派发器- 获取
BeanFactory - 从
BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster - 如果上一步没有配置,就创建一个
SimpleApplicationEventMulticaster - 将创建的
ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入 
- 获取
 onRefresh():留给子容器(子类)- 子类重写这个方法,在容器刷新的时候可以自定义逻辑;
 
registerListeners():给容器中将所有项目里面的ApplicationListener注册进来;从容器中拿到所有的
ApplicationListener将每个监听器添加到事件派发器中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)派发之前步骤产生的事件
创建Bean准备、完成
有代理对象就用,没有就创建,然后在初始化前后准备各种后置处理器,创建完成后放入各种Map
finishBeanFactoryInitialization(beanFactory):初始化所有剩下的单实例beanbeanFactory.preInstantiateSingletons():初始化剩下的单实例bean获取容器中的所有Bean,依次进行初始化和创建对象
获取Bean的定义信息:
RootBeanDefinition判断Bean不是抽象的,是单实例的,不是懒加载
判断是否是
FactoryBean,是否是实现FactoryBean接口的Bean如果不是工厂Bean。利用
getBean(beanName):创建对象这个
getBean(beanName)就是平时测试类中用到的ioc.getBean()doGetBean(name, null, null, false)先获取缓存中保存的单实例Bean。
this.singletonObjects.get(beanName),如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)可以从
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256)属性获取到缓存中获取不到,开始Bean的创建对象流程,使用
BeanFactory标记当前bean已经被创建
markBeanAsCreated(beanName)获取Bean的定义信息
【获取当前Bean依赖的其他Bean,
mbd.getDependsOn(),如果有按照就getBean()把依赖的Bean先创建出来】启动单实例Bean的创建流程
进入匿名类的
createBean(beanName, mbd, args)方法(可以打断点进入)Object bean = resolveBeforeInstantiation(beanName, mbdToUse)[给 BeanPostProcessors 一个返回代理而不是目标 Bean 实例的机会]:让BeanPostProcessor先拦截返回代理对象【
InstantiationAwareBeanPostProcessor提前执行,就是在AOP中先于BeanPostProcessor执行的那个组件】- 先触发:
postProcessBeforeInstantiation()实例化前的后处理 - 如果有返回值,触发:
postProcessAfterInitialization()初始化后的后处理 
- 先触发:
 如果前面的
InstantiationAwareBeanPostProcessor没有返回代理对象,调用第4步创建BeanObject beanInstance = doCreateBean(beanName, mbdToUse, args):创建Bean【创建Bean实例】:
createBeanInstance(beanName, mbd, args)利用工厂方法或者对象的构造器创建出Bean实例
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)[允许后处理器修改合并的 Bean 定义。]调用
MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName)【Bean属性赋值】
populateBean(beanName, mbd, instanceWrapper)赋值之前:
拿到
InstantiationAwareBeanPostProcessor后置处理器:postProcessAfterInstantiation()实例化后的后处理(对应上面(8.2))拿到
InstantiationAwareBeanPostProcessor后置处理器:ibp.postProcessPropertyValues()后处理属性值
开始赋值:
应用Bean属性的值;为属性利用setter方法等进行赋值:
applyPropertyValues(beanName, mbd, bw, pvs)
【Bean初始化】
initializeBean(beanName, exposedObject, mbd):【执行Aware接口方法】
invokeAwareMethods(beanName, bean):执行xxxAware接口的方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware【在初始化之前应用 BeanPostProcessors】
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)BeanPostProcessor.postProcessBeforeInitialization()【执行初始化方法】
invokeInitMethods(beanName, wrappedBean, mbd)- 是否是
InitializingBean接口的实现;执行接口规定的初始化 - 是否自定义初始化方法
 
- 是否是
 【在初始化之后应用 BeanPostProcessors】
applyBeanPostProcessorsAfterInitializationBeanPostProcessor.postProcessAfterInitialization()
注册Bean的销毁方法
将创建的Bean添加到缓存中
singletonObjects
ioc容器就是这些Map,很多的Map里面保存了单实例Bean,环境信息...
所有Bean都利用getBean创建完成以后:检查所有的Bean是否是SmartInitializingSingleton[智能初始化单例]接口的,如果是,就执行afterSingletonsInstantiated()在单例实例化之后
容器创建完成
finishRefresh():完成BeanFactory的初始化创建工作,IOC容器就创建完成initLifecycleProcessor():初始化和生命周期有关的后置处理器:LifecycleProcessor默认从容器中找是否有
lifecycleProcessor的组件【LifecycleProcessor】;如果没有
new DefaultLifecycleProcessor();加入到容器
onRefresh()写一个
LifecycleProcessor的实现类,可以在BeanFactory的生命周期onRefresh()、onClose()处拦截
getLifecycleProcessor().onRefresh()拿到前面定义的生命周期处理器(
BeanFactory),回调onRefresh()publishEvent(new ContextRefreshedEvent(this)):发布容器刷新完成事件LiveBeansView.registerApplicationContext(this)
Spring注解开发_Spring容器创建概述的更多相关文章
- spring注解开发:容器中注册组件方式
		
1.包扫描+组件标注注解 使用到的注解如下,主要针对自己写的类 @Controller @Service @Repository @Component @ComponentScan 参考 spring ...
 - 浅尝Spring注解开发_Servlet3.0与SpringMVC
		
浅尝Spring注解开发_Servlet 3.0 与 SpringMVC 浅尝Spring注解开发,基于Spring 4.3.12 Servlet3.0新增了注解支持.异步处理,可以省去web.xml ...
 - Spring注解开发-全面解析常用注解使用方法之生命周期
		
本文github位置:https://github.com/WillVi/Spring-Annotation/ 往期文章:Spring注解开发-全面解析常用注解使用方法之组件注册 bean生命周期  ...
 - Spring注解开发系列Ⅵ --- AOP&事务
		
注解开发 --- AOP AOP称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等待,Struts2的拦截器设计就是基于AOP的思想,横向重复,纵向抽取.详细的AO ...
 - 浅尝Spring注解开发_自定义注册组件、属性赋值、自动装配
		
Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含自定义扫描组件.自定义导入组件.手动注册组件.自动注入方法和参数.使用Spring容器底层组件等 配置 @Confi ...
 - 浅尝Spring注解开发_Bean生命周期及执行过程
		
Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含Bean生命周期.自定义初始化方法.Debug BeanPostProcessor执行过程及在Spring底层中的应 ...
 - 浅尝Spring注解开发_AOP原理及完整过程分析(源码)
		
浅尝Spring注解开发_AOP原理及完整过程分析(源码) 浅尝Spring注解开发,基于Spring 4.3.12 分析AOP执行过程及源码,包含AOP注解使用.AOP原理.分析Annotation ...
 - Annotation(三)——Spring注解开发
		
Spring框架的核心功能IoC(Inversion of Control),也就是通过Spring容器进行对象的管理,以及对象之间组合关系的映射.通常情况下我们会在xml配置文件中进行action, ...
 - spring注解开发中常用注解以及简单配置
		
一.spring注解开发中常用注解以及简单配置 1.为什么要用注解开发:spring的核心是Ioc容器和Aop,对于传统的Ioc编程来说我们需要在spring的配置文件中邪大量的bean来向sprin ...
 
随机推荐
- 并发包下常见的同步工具类(CountDownLatch,CyclicBarrier,Semaphore)
			
在实际开发中,碰上CPU密集且执行时间非常耗时的任务,通常我们会选择将该任务进行分割,以多线程方式同时执行若干个子任务,等这些子任务都执行完后再将所得的结果进行合并.这正是著名的map-reduce思 ...
 - Spring Bean生命周期回调
			
参阅官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory ...
 - TCP(三)
			
1.三次握手 置位概念:根据TCP的包头字段,存在3个重要的标识ACK.SYN.FIN ACK:表示验证字段 SYN:位数置1,表示建立TCP连接 FIN:位数置1,表示断开TCP连接 三次握手过程说 ...
 - Living Documentation
			
Living Documentation Living documentation in legacy systems Living documentation, which comes from t ...
 - 前端网络安全——Cookies
			
一.Cookies特性 1.前端数据存储 2.后端通过http头设置 3.请求时通过http头传给后端 4.前端可读写 5.遵守同源策略 二.Cookies内容 1.域名 2.有效期,删除cookie ...
 - mysql各个集群方案的优劣
			
集群的好处 高可用性:故障检测及迁移,多节点备份. 可伸缩性:新增数据库节点便利,方便扩容. 负载均衡:切换某服务访问某节点,分摊单个节点的数据库压力. 集群要考虑的风险 网络分裂:群集还可能由于网络 ...
 - DOM节点详解
			
@ 目录 学习总结 1. 什么是 DOM 2. HTMLDOM 3. 元素获取 元素获取方式: 元素节点的属性操作 4. Node 对象的属性和方法 常用属性 常用方法 5. 事件处理 事件驱动编程 ...
 - Java中jdk安装与环境变量配置
			
Java中jdk安装与环境变量配置 提示:下面是jdk1.7和jdk1.8的百度网盘链接 链接:https://pan.baidu.com/s/1SuHf4KlwpiG1zrf1LLAERQ 提取码: ...
 - dev分支代码覆盖master分支代码
			
将develop分支上的代码完全覆盖master分支, 1. 切换到master分支 git checkout master 2. 执行以下命令 git reset --hard origin/dev ...
 - Git---git的常用操作
			
git三种状态的转换 git状态切换时的常用命令 1. git管理工作目录 git init # 会增加.git文件夹 2. git的三种状态 工作区 暂存区 本地仓库 3. 提交到暂存区 git a ...