标签:code ssm event oge 用户 config str 进一步 customize
spring ioc容器的加载,大体上经过以下几个过程: 资源文件定位、解析、注册、实例化
1.资源文件定位:主要发生在ApplicationContext中,由于applicationContext继承于ResourceLoader,所以调用getResource()方法,将外部的资源解析成Resource类
ac利用loadBeanDefininiation()方法,负责读取Resource;将Resource的解析交给XMLbeanDefiniationReader去处理,
将XML文档解析成w3c的Document文档,BeanDefinitionDocumentReader进一步解析,BeanDefinitionDocumentReader将Document,交给BeanDefiniationParserDetegate去处理(装饰),如果是标准的NameSpace文档(import、alias、bean、beans),在内部解析,如果不是标准的文档,会委托合适的NameSpaceHander去处理进行解析,将结果封装到BeanDefiniationHolder,最后调用一个工具类来完成对BeanDefinintion的注册
3.注册
Bean的注册是在BeanFactory中完成的,BeanFactory最常用的一个实现类是DefaultListableBeanFactory,它实现了BeanDefinitionRegistry接口,调用了registerBeanDefinition()方法,从而对BeanDefinition进行注册.
所谓的注册就是将BeanDefinition的name和实例保存到一个CurrentHashMap中,最常用的实现DefaultListableBeanFactory,其中的字段就是beanDefinitionMap,是一个ConcurrentHashMap
4.实例化:
注册也完成之后,在BeanFactory的getBean()方法之中,会完成初始化
容器初始化的核心
//1.刷新前的预处理
// Prepare this context for refreshing.
prepareRefresh();
//2.获取beanfactory
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3.beanFactory的预准备工作
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
?
try {
//4.为BeanFactory准备工作完成后,添加一些的后置处理器(用户自定义)
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//5.执行beanFacotry的后置处理器
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//6.注册Bean的后置处理器
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//7.初始化消息资源管理(主要用于国际化、消息绑定、消息解析)
// Initialize message source for this context.
initMessageSource();
//8.初始化事件的派发器
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
//9.重新刷新容器,留给子类重写该方法,进行自定义
// Initialize other special beans in specific context subclasses.
onRefresh();
//10.将容器中的ApplicationListener注册进来
// Check for listener beans and register them.
registerListeners();
//11.初始化所有的非懒加载的Bean实例
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//12.完成BeanFactory的初始化创建工作
// Last step: publish corresponding event.
finishRefresh();
//IOC容器创建完成
(1), initPropertySources初始化一些属性设置
(2),getEnvironment().validateRequiredProperties();校验属性和环境的相关设置
(3), this.earlyApplicationEvents = new LinkedHashSet<>();保存容器中的一些早期事件
(1)refreshBeanFactory();创建BeanFactory对象
1.如果有BeanFactory,就清空
?
2.createBeanFactory()创建DefaultListableBeanFactory对象
?
3.beanFactory.setSerializationId(getId());设置标识符
?
4.customizeBeanFactory()允许用户自定义一些设置
?
5.loadBeanDefinitions()解析XML文件并注册成BeanDefinition对象
?
<1>创建XMLBeanDefinitionReader对象,new XmlBeanDefinitionReader(beanFactory);
?
beanFactory其实是BeanDefinitionRegistry对象,因为DefaultListableBeanFactory实现了
?
BeanDefinitionRegistry接口
?
<2>设置并初始化XMLBeanDefinitionReader对象
?
<3>loadBeanDefinition(beanDefinitionReader)解析XML文件并注册成BeanDefinition对象
?
的真正方法
?
其内部: XmlBeanDefinitionReader无法直接解析配置文件,所以利用了ResourceReader
?
将Location配置文件封装成Resource,然后调用重载的方法,先将Resource转换成
?
InputStream在解析成w3c的Doucment对象,最后调用RegisterBeanDefinitions()
?
RegisterBeanDefinitions()内部实现:创建一个BeanDefinitionDocumentReader对象 起到路由的作用
?
1.该对象会委托BeanDefinitionParserDelegate()进行真正的解析doc
?
调用delegate.parseBeanDefinitionElement(ele),如果是标准的NameSpace文档
?
(import、alias、bean、beans),在内部解析,如果不是标准的文档,会委托合适的
?
NameSpaceHander去处理进行解析,将结果封装到BeanDefiniationHolder
?
2.调用Delegate对BeanDefinition进行装饰
?
3.最后调用工具类方法,进行注册,其实调用的是DefaultListableBeanFactory中的
?
registerBeanDefinition(),该方法主要是beanName放到队列(beanDefinitionNames) 里,然后把BeanDefinition放到beanDefinitionMap.put(beanName, beanDefinition) <concurrentHashMap>
(2)getBeanFactory() 获取BeanFactory对象,并返回ConfigurableListableBeanFactory对象
执行BeanFactoryPostProcessor的方法;
里有2个接口BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessors的子类)、BeanFactoryPostProcessors都将会执行它们的后置处理器的方法
1.先执行BeanDefinitionRegistryPostProcessor的方法,(beanDefinition将要被加载在beanfactory中但是还没有实例化,作用是用于自己添加beanDefinition)
1)、获取所有的BeanDefinitionRegistryPostProcessor;
2)、看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
postProcessor.postProcessBeanDefinitionRegistry(registry)
3)、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor;
postProcessor.postProcessBeanDefinitionRegistry(registry)
4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors;
postProcessor.postProcessBeanDefinitionRegistry(registry)
2.否则的话,BeanFactoryPostProcessor的方法(beanfactory标准初始化之后,来定制beanfactory的内容,所有的beanDefinition已经保存到了beanfactory中但是还没有实例化)
1)、获取所有的BeanFactoryPostProcessor
2)、看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、
postProcessor.postProcessBeanFactory()
3)、在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
不同接口类型的BeanPostProcessor,在Bean创建执行前后是不一样的
BeanPostProcessor、 DestructionAwareBeanPostProcessor、 InstantiationAwareBeanPostProcessor、 SmartInstantiationAwareBeanPostProcessor、 MergedBeanDefinitionPostProcessor【internalPostProcessors】、
(1)先获取所有的BeanPostProcessor,这些后置处理器可以通过PriorityOrdered、Ordered接口来执行优先级
(2)先将实现了PriorityOrdered优先级接口的BeanPostProcessor注册到BeanFactory
把每一个BeanPostProcessor注册到BeanFactory中
?
beanFactory.addBeanPostProcessor(postProcessor);
(3)在注册实现了Ordered接口的BeanPostProcessor
(4)最后注册没有实现任何优先级接口的
(5)、最后注册一个ApplicationContextListenerDetector的后置处理器,用于在Bean创建完成后检查是否为ApplicationContextListener,是的话,就会调用ApplicationContext.addApplicationListener((ApplicationListener<?>) bean)将其添加到容器中
1.获取BeanFactory
2.看容器中是否有id为messageSource的,类型是MessageSource的组件
如果没有就创建一个DelegatingMessageSource,然后把messageSource注入到容器,以后获取国际化的资源可以根据messageSource来获取
(基于事件派发的组件)
1.获取BeanFactory
2.看容器中是否有id为applicationEventMulticaster的组件
如果没有就创建一个SimpleApplicationEventMulticaster,然后把它注入到容器.
子类重写这个方法,在容器刷新的时候可以自定义逻辑;
1.从容器中获取所有的ApplicationListener
2.将每个监听器添加到事件派发器中; getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
实际上调用的是DefaultListableBeanFactory的preInstantiateSingleton()方法
preInstantiateSingleton()
1.遍历BeanDefinitionMap
?
2.在遍历的时候,调用getMergedLocalBeanDefinition(beanName)将其转换成RootBeanDefinition
注意:普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition,这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作
3.在遍历的时候,判断要实例化Bean1.非抽象2.是单例3.非延迟加载 4.在遍历的时候,先判断当前Bean是否为FactoryBean的实现(false,直接调用getBean(beanName))在判断是否为 SmartFactoryBean的实现,假如Bean是SmartFactoryBean的实现并且为eagerInit(渴望加载),也会调用 getBean(beanName)立即实例化该Bean getBean(beanName)核心doGetBean()为父类AbstractBeanFactory类的doGetBean方法 doGetBean()方法 1.先判断本地的单例缓存中是否缓存过该Bean,如果有缓存就直接从缓存中获取 2.然后进行一些基本检验,比如检查depend-on属性,用来保证具有依赖关系的Bean先被加载 3.调用createBean(beanName, mbd, args)用于创建单实例对象 1.resolveBeforeInstantiation(); 创建bean实例前,让BeanPostProcessor先拦截,是否能返回代理对象; 也就是给beanPostProcessor一个返回bean的代理对象机会 内部是【InstantiationAwareBeanPostProcessor】这个拦截器(和AOP有关) 先触发:postProcessBeforeInstantiation(beanClass, beanName); 如果有返回值Object bean ,就不会创建bean了在调用 postProcessAfterInitialization(beanClass, beanName)并返回代理bean [InstantiationAwareBeanPostProcessor]没有的代理的bean调用doCreateBean() 2.doCreateBean() AbstractAutowireCapableBeanFactory 的doCreateBean()方法 <1>.创建Bean实例,并包装成BeanWrapper createBeanInstance()方法 判断当前的Bean里面使用的是空参构造还是有参数构造,然后通过反射生成Bean的实 例。看到前面有一步makeAccessible,这意味着即使Bean的构造函数是private、 protected的,依然不影响Bean的构造。这里被实例化出来的Bean并不会直接返回, 而是会被包装为BeanWrapper <2>.允许后置处理器对其进行修改Bean定义 applyMergedBeanDefinitionPostProcessors() 会调用MergedBeanDefinitionPostProcessor的 postProcessMergedBeanDefinition(mbd, beanType, beanName); <3>.属性注入 populateBean()方法 1)、在赋值之前,拿到InstantiationAwareBeanPostProcessor后置处理器 调用postProcessAfterInstantiation(); 2)、继续拿到InstantiationAwareBeanPostProcessor后置处理器; 调用postProcessPropertyValues(); 赋值操作 3)、applyPropertyValues() 真正为属性赋值的方法 首先进行深拷贝(指的是深度拷贝,遍历PropertyValue然后一个一个赋值到 一个新的List,是为了解析Values值中的所有引用),然后在调用 bw.setPropertyValues(new MutablePropertyValues(deepCopy)),遍历 deepcopy对象拿到对应的set方法并将方法的可见性设置为true,最后利用反 射的机制,对Bean通过反射调用set()方法 (1)拿到写方法并将方法的可见性设置为true (2)拿到Value值,对Bean通过反射调用写方法 <4>.初始化Bean initializeBean()方法 1).执行Aware()方法,调用invokeMethodAware(beanName, bean)方法 ,执行 xxxAware接口的方法 实现BeanNameAware/BeanClassLoaderAware/BeanFactoryAware.... 才会进行 调用,aware主要是属性赋值后获取其中的信息并且自定义修改 2).执行后置处理器在初始化之前 applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName); BeanPostProcessor.postProcessBeforeInitialization(); 3).执行初始化的方法invokeInitMethods(beanName, wrappedBean, mbd) <1>、是否是InitializingBean接口的实现;执行接口规定的初始化; <2>、尝试去拿init-method,假如有的话,通过反射,调用initMethod; 因此,两种方法各有优劣:使用实现InitializingBean接口的方式效率更高一点,因为init-method方法是通过反射进行调用的(JVM无法优化在内存中的动态对象);从另外一个角度讲,使用init-method方法之后和Spring的耦合度会更低一点 4).执行后置处理器在初始化之后applyBeanPostProcessorsAfterInitialization BeanPostProcessor.postProcessAfterInitialization(); 5).注册bean的销毁方法,在容器关闭之前会自动的进行调用 registerDisposableBeanIfNecessary(beanName, bean, mbd); 要注册销毁方法,Bean需要至少满足以下三个条件之一: (1)Bean是DisposableBean的实现类,此时执行DisposableBean的接口方法 destroy() (2)Bean标签中有配置destroy-method属性,此时执行destroy-method配置指定的 方法 (3)当前Bean对应的BeanFactory中持有DestructionAwareBeanPostProcessor接口 的实现类,此时执行 DestructionAwareBeanPostProcessor的接口方法 postProcessBeforeDestruction 4.创建好Bean后,将其添加到容器中 5.非单例非原型调用 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);(了解)如果bean是 FactoryBean的实现类的话,调用getObject()方法获取真正的对象。
流程总结:
[
1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor 默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new
DefaultLifecycleProcessor();然后到加入到容器中
写一个LifecycleProcessor的实现类,可以在BeanFactory刷新或者关闭的时候进行调用 void onRefresh(); void onClose();
2)、 getLifecycleProcessor().onRefresh();
拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
发布事件流程:1.获取事件派发器
2.multicastEvent派发事件
3.获取到所有的ApplicaitonListener
4.判断是否需要已异步还是同步的方式进行执行listener的onApplicationEvent()方法
标签:code ssm event oge 用户 config str 进一步 customize
原文地址:https://www.cnblogs.com/itxiaok/p/10356683.html