@TOC# Spring系列
记录在程序走的每一步___auth:huf
临近放假;预祝同学们国庆节日快乐,祝祖国繁荣昌盛; 因为近期的工作,以及上生产版本比较频繁;所以文章有稍微更新不及时; 国庆期间会给大家把文章补齐; 其实我们一直看源码 看得都是Spring的启动原理; Spring的启动原理 涵盖了我之前所有文章源码的集合;这里没有AOP 如果精准一点说 是有一丢丢AOP的知识点体系; AOP的源码国庆后会更新出来给大伙;在Spring中 即使没有代理对象 我们依然可以很快乐的使用Spring; 但是AOP又是Spring的高亮之一; 也是面试的重点 也是知识体系掌握的重点; 所以就独立开来 后面单独的去讲这一块;
Spring 的启动原理;
该篇章为源码篇章 所有解释在源码里边;
/**
* auth:huf
*/
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class testMain {
public static void main(String[] args) {
创建启动上下文; 那么我们就从这个方法开始进行深入的解析整个过程;
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(testMain.class);
TeacharServiceImpl teacharServiceImpl = (TeacharServiceImpl) context.getBean("teacharServiceImpl");
System.out.println(teacharServiceImpl);
}
}
public AnnotationConfigApplicationContext() {
在其方法的内部 我们可以看到; 在Spring中 所有的东西的开始 就是类; 包括一开始使用的BeanFactory
或者是说BeanPostProcessor 在一开始 肯定是需要一个承载的东西去承载 所有一切的开始;
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
该承载器就是DefaultListableBeanFactory 一开始通过this this是什么
就是AnnotationConfigApplicationContext本身
然后传入到AnnotatedBeanDefinitionReader方法内部
内部通过unwrapDefaultListableBeanFactory方法 给你强转成为
DefaultListableBeanFactory 这个就是梦的开始; 下面有该方法详细解说;
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
之后就加入Component 的Filters 便于解析Component类需要用到的; 该方法不详说
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
AnnotatedBeanDefinitionReader
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
根据上述所说 我们通过强转得到了一个DefaultListableBeanFactory
我这里是这样理解这个东西的. 一切都需要一个开端. 一切都需要开始的一个步骤;
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
一开始创建了一个比较器;该比较器里面(排序等) 类型比较; 然后放进去BeanFactory
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
然后创建一个AutowrireCandiate的自动解析器; 主要用于BeanFactory 自动解析;
主要解析是否可以依赖注入; 这里源码感兴趣的同学可以自行点进去看其作用;
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
创建一个List 放置前置 BeanDefinition 它 就是BeanDefintionHolder
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
这ConfigurationClassPostProcessor
其实它是BeanFactoryPostProcessor 它的作用是用于配置文件的扫描 等等作用
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
这个就很简单了 这个一看这个.Class 就能明白.它是自定义注解的PostProcessor
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
这个是@Resource 那个注解的 BeanPostProcessor
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
这里是JPA的 的一些注解PostProcessor
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
这里是Spring事件监听的PostProcessor
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));
}
这里是Spring事件相关的PostProcessor
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;
}
这个方法就是这么简单; 也就是说 一开始启动的时候 就会创建一个空的BeanFactory 并且向里面设置一些内容;这些内容是之后我们要用到的内容 请注意 这些内容并没有实例化; 注意!! 这些内容并没有实例化; 仅仅是生成相对应的RootBeanDefinition 并且放到registry 里边 也就是BeanFactory里边!!!
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
这个This 就是刚刚上面说的那些内容
this();
这里是将传入的那个testMain.class 进行解析;生成BeanDefinition 放进去BeanFactorgy里面
这两行代码其实并不难; 同学们可以自己点进去看一下; 别看到代码多就慌;
register(componentClasses);
重点看这行代码 重点!!重点!!重点!!!
refresh();
}
refresh
refresh():加载或刷新持久化的 配置,可能是XML文件、属性文件或关系数据库中存储的。由于这是一个启动方法,如果失败,它应 该销毁已经创建的单例,以避免暂用资源。换句话说,在调用该方法之后,应该实例化所有的单例, 或者根本不实例化单例 。
ApplicationContext关闭之后不代表JVM也关闭了,ApplicationContext是 属于JVM的,说白了ApplicationContext也是JVM中的一个对象。
在Spring的设计中,也提供可以刷新的ApplicationContext和不可以刷新的ApplicationContext
可刷新的
AbstractRefreshableApplicationContext extends AbstractApplicationContext
不可刷新的
GenericApplicationContext extends AbstractApplicationContext
AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以它是不能刷新 的。 AnnotationConfigWebApplicationContext继承的是 AbstractRefreshableWebApplicationContext,所以它是可以刷的。 上面说的不能刷新是指不能重复刷新,只能调用一次refresh方法,第二次时会报错。
一下就是关键重点代码; 我前几篇文章 全部都有写; 但是可能写得不够详细;这里我们再从新写一次;
里面的代码我就不再继续累赘; 因为里面代码 我们基本上都看过一次;
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
---------------------------------
这里是往BeanFactory 继续set 其他属性 并且里面有一个方法是:
--initPropertySources() 该方法就是初始化property 里面的属性;
有一些属性是可以设置成必须注入的属性 我们以前再整合SpringMVC的时候 再web.xml里面就有配置;
直白一点就是一些Key Value键值对;
以下就是详细:
1记录启动时间
2可以允许子容器设置一些内容到Environment中
3验证Environment中是否包括了必须要有的属性
prepareRefresh(); --源码
---------------------------------
进行BeanFactory的refresh,在这里会去调用子类的 refreshBeanFactory方法,
具体子类是怎么刷新的得看子类,然后再调用子类的 getBeanFactory方法,
重新得到一个BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); --源码
---------------------------------
prepareBeanFactory(beanFactory);--源码
1:设置beanFactory的类加载器
2:设置表达式解析器:StandardBeanExpressionResolver,用来解析Spring中的表达式
3:添加PropertyEditorRegistrar:ResourceEditorRegistrar,PropertyEditor类型转化器注 册器,用来注册一些默认的PropertyEditor
4:添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个 BeanPostProcessor,用来执行EnvironmentAware、ApplicationEventPublisherAware 等回调方法
5:添加ignoredDependencyInterface:可以向这个属性中添加一些接口,
如果某个类实现 了这个接口,并且这个类中的某些set方法在接口中也存在,
那么这个set方法在自动注入的 时候是不会执行的,比如EnvironmentAware这个接口,
如果某个类实现了这个接口,那么 就必须实现它的setEnvironment方法,
而这是一个set方法,和Spring中的autowire是冲突 的,
那么Spring在自动注入时是不会调用setEnvironment方法的,
而是等到回调Aware接 口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性 的){
a. EnvironmentAware
b. EmbeddedValueResolverAware
c. ResourceLoaderAware
d. ApplicationEventPublisherAware
e. MessageSourceAware
f. ApplicationContextAware
g 另外其实在构造BeanFactory的时候就已经提前添加了另外三个:
h. BeanNameAware
i. BeanClassLoaderAware
j. BeanFactoryAware
}
6:添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型 找bean{
a. BeanFactory.class:当前BeanFactory对象
b. ResourceLoader.class:当前ApplicationContext对象
c. ApplicationEventPublisher.class:当前ApplicationContext对象
d. ApplicationContext.class:当前ApplicationContext对象
}
7:添加一个Bean的后置处理器:ApplicationListenerDetector,
是一个 BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,
如果是则把这个 Bean添加到ApplicationContext中去,
注意一个ApplicationListener只能是单例的
8: 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,
是一个 BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,
如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法
设置给该Bean。
9:添加一些单例bean到单例池{
a. "environment":Environment对象
b. "systemProperties":System.getProperties()返回的Map对象
c. "systemEnvironment":System.getenv()返回的Map对象
}
---------------------------------
try {
提供给AbstractApplicationContext的子类进行扩 展,具体的子类,可以继续向BeanFactory中再添加一些东西
postProcessBeanFactory(beanFactory); --源码
---------------------------------
记录beanPostProcess 创建时间
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); --源码
---------------------------------
invokeBeanFactoryPostProcessors(beanFactory);--源码
执行BeanFactoryPostProcessor{
1:此时在BeanFactory中会存在一个BeanFactoryPostProcessor: ConfigurationClassPostProcessor,它也是一个 BeanDefinitionRegistryPostProcessor
2:从BeanFactory中找到类型为BeanDefinitionRegistryPostProcessor的beanName,也就 是ConfigurationClassPostProcessor, 然后调用BeanFactory的getBean方法得到实例 对象
3:执行**ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()**方法:[
a. 解析AppConfig类
b. 扫描得到BeanDefinition并注册
c. 解析@Import,@Bean等注解得到BeanDefinition并注册
d. ConfigurationClassPostProcessor是如何工作的 放到下个篇章 这里留个坑
e. 在这里,我们只需要知道在这一步会去得到BeanDefinition,而这些BeanDefinition中 可能存在BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,所以 执行完ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方 法后,还需要继续执行其他BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法
]
4:执行其他BeanDefinitionRegistryPostProcessor的 **postProcessBeanDefinitionRegistry()**方法
5:执行所有BeanDefinitionRegistryPostProcessor的**postProcessBeanFactory()**方法
6:从BeanFactory中找到类型为BeanFactoryPostProcessor的beanName,而这些 BeanFactoryPostProcessor包括了上面的BeanDefinitionRegistryPostProcessor
7:执行还没有执行过的BeanFactoryPostProcessor的**postProcessBeanFactory()**方法
}
---------------------------------
因为上面的步骤完成了扫描,这个过程中程序员 可能自己定义了一些BeanPostProcessor,
在这一步就会把BeanFactory中所有的 BeanPostProcessor找出来并实例化得到一个对象,
并添加到BeanFactory中去(属性 beanPostProcessors),
最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,
这里是为了把ApplicationListenerDetector移动到最后)
registerBeanPostProcessors(beanFactory);--源码
---------------------------------
到此,所有的BeanFactoryPostProcessor的逻辑都执行完了,主要做的事情就是得到 BeanDefinition并注册到BeanFactory中
beanPostProcess.end();--源码
---------------------------------
如果BeanFactory中存在一个叫做"messageSource"的 BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的 messageSource属性,让ApplicationContext拥有国际化的功能
initMessageSource();--源码
---------------------------------
如果BeanFactory中存在一个叫 做"applicationEventMulticaster"的BeanDefinition,
那么就会把这个Bean对象创建出来并 赋值给ApplicationContext的applicationEventMulticaster属性,
让ApplicationContext拥有 事件发布的功能
initApplicationEventMulticaster();--源码
---------------------------------
提供给AbstractApplicationContext的子类进行扩展,没用
onRefresh();--源码
---------------------------------
从BeanFactory中获取ApplicationListener类型的beanName,
然后添加 到ApplicationContext中的事件广播器applicationEventMulticaster中去,
到这一步因为 FactoryBean还没有调用getObject()方法生成Bean对象,
所以这里要在根据类型找一下 ApplicationListener,记录一下对应的beanName
registerListeners();--源码
---------------------------------
完成BeanFactory的初始化,主要就是实例化 非懒加载的单例Bean
finishBeanFactoryInitialization(beanFactory);--源码
---------------------------------
finishRefresh();--源码
BeanFactory的初始化完后,就到了Spring启动的最后一步了
设置ApplicationContext的lifecycleProcessor,默认情况下设置的是 DefaultLifecycleProcessor
调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所 有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命 周期扩展机制
发布ContextRefreshedEvent事件
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
contextRefresh.end();
}
}
}
执行BeanFactoryPostProcessor
- 执行通过ApplicationContext添加进来的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法
- 执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法
- 执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法
- 执行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法
- 执行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
- 执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的 postProcessBeanFactory()方法
- 执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的 postProcessBeanFactory()方法
- 执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的 postProcessBeanFactory()方法
- 执行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法