扬州专业网站制作,微信有哪些不正经的公众号,wordpress 伪静态404,新手搭建网站概述
我们说的Spring启动#xff0c;就是构造ApplicationContext对象以及调用refresh()方法的过程。
Spring启动过程主要做了这么几件事情#xff1a;
构造一个BeanFactory对象解析配置类#xff0c;得到BeanDefinition#xff0c;并注册到BeanFactory中 解析ComponentS…概述
我们说的Spring启动就是构造ApplicationContext对象以及调用refresh()方法的过程。
Spring启动过程主要做了这么几件事情
构造一个BeanFactory对象解析配置类得到BeanDefinition并注册到BeanFactory中 解析ComponentScan此时就会完成扫描解析Import解析Bean… ApplicationContext支持国际化需要初始化MessageSource对象ApplicationContext支持事件机制需要初始化ApplicationEventMulticaster对象把用户定义的ApplicationListener对象添加到ApplicationContext中等Spring启动完了发布事件创建非懒加载的单例Bean对象并存在BeanFactory的单例池中调用Lifecycle Bean的start()方法发布ContextRefreshedEvent事件
Spring启动过程中要创建非懒加载的单例Bean对象需要用到BeanPostProcessor所以Spring在启动过程中需要做两件事
生成默认的BeanPostProcessor对象并添加到BeanFactory中 AutowiredAnnotationBeanPostProcessor处理Autowired、ValueCommonAnnotationBeanPostProcessor处理Resource、PostConstruct、PreDestroyApplicationContextAwareProcessor处理ApplicationContextAware等回调 找到外部用户所定义的BeanPostProcessor对象类型为BeanPostProcessor的Bean对象并添加到BeanFactory中
BeanFactoryPostProcessor
BeanPostProcessor表示Bean的后置处理器是用来对Bean进行加工的类似的BeanFactoryPostProcessor理解为BeanFactory的后置处理器用来用对BeanFactory进行加工的。
Spring支持用户定义BeanFactoryPostProcessor的实现类Bean来对BeanFactory进行加工比如
Component
public class FireBeanFactoryPostProcessor implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition beanFactory.getBeanDefinition(userService);// 修改BeanDefinition对象的属性值发生在Spring启动时创建单例Bean之前后面创建Bean时此处的修改会生效beanDefinition.setAutowireCandidate(false);}
}在ApplicationContext内部有一个核心的DefaultListableBeanFactory它实现了ConfigurableListableBeanFactory和BeanDefinitionRegistry接口所以ApplicationContext和DefaultListableBeanFactory是可以注册BeanDefinition的但是ConfigurableListableBeanFactory是不能注册BeanDefinition的只能获取BeanDefinition然后做修改。
// AnnotationConfigApplicationContext继承GenericApplicationContext
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {private final DefaultListableBeanFactory beanFactory;...
}public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactoryimplements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {// ConfigurableListableBeanFactory只能获取BeanDefinition不能注册BeanDefinition...
}Spring提供了一个BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcessor用以注册BeanDefinition对象。
BeanDefinitionRegistryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {// 实现该接口并实现该方法可以注册BeanDefinition对象void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;}自定义类注册BeanDefinition例如
Component
public class FireBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {AbstractBeanDefinition beanDefinition BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();beanDefinition.setBeanClass(User.class);registry.registerBeanDefinition(user, beanDefinition);}Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition beanFactory.getBeanDefinition(userService);beanDefinition.setAutowireCandidate(false);}
}refresh()
构造ApplicationContext对象时调用refresh()方法如下
public AnnotationConfigApplicationContext(Class?... componentClasses) {// 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScannerthis();register(componentClasses);refresh();
}refresh()是在接口ConfigurableApplicationContext中定义的如下
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {/*** Load or refresh the persistent representation of the configuration, which* might be from Java-based configuration, an XML file, a properties file, a* relational database schema, or some other format.* pAs this is a startup method, it should destroy already created singletons* if it fails, to avoid dangling resources. In other words, after invocation* of this method, either all or no singletons at all should be instantiated.* throws BeansException if the bean factory could not be initialized* throws IllegalStateException if already initialized and multiple refresh* attempts are not supported*/void refresh() throws BeansException, IllegalStateException;
}
注释意思是加载或刷新持久化的配置可能是XML文件、属性文件或关系数据库中存储的。由于这是一个启动方法如果失败它应该销毁已经创建的单例以避免占用资源。换句话说在调用该方法之后应该实例化所有的单例或者根本不实例化单例 。注意ApplicationContext关闭之后不代表JVM也关闭了ApplicationContext是属于JVM的说白了ApplicationContext也是JVM中的一个对象。
有两种ApplicationContext分为可刷新和不可刷新只能刷新一次不能重复刷新如下
// 刷新的ApplicationContext
AbstractRefreshableApplicationContext extends AbstractApplicationContext
// 不可刷新的ApplicationContext
GenericApplicationContext extends AbstractApplicationContextAnnotationConfigApplicationContext继承的是GenericApplicationContext所以它是不能刷新的。AnnotationConfigWebApplicationContext继承的是AbstractRefreshableWebApplicationContext所以它是可以刷新的。
下面以AnnotationConfigApplicationContext为例子来介绍refresh的底层实现流程
在调用AnnotationConfigApplicationContext的构造方法之前会调用父类GenericApplicationContext的无参构造方法会构造一个BeanFactory为DefaultListableBeanFactory构造AnnotatedBeanDefinitionReader主要作用添加一些基础的PostProcessor同时可以通过reader进行BeanDefinition的注册同时对BeanFactory进行设置和添加PostProcessor后置处理器 设置dependencyComparatorAnnotationAwareOrderComparator它是一个Comparator是用来进行排序的会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序在日常开发中可以利用这个类来进行排序设置autowireCandidateResolverContextAnnotationAutowireCandidateResolver用来解析某个Bean能不能进行自动注入比如某个Bean的autowireCandidate属性是否等于true向BeanFactory中添加ConfigurationClassPostProcessor对应的BeanDefinition它是一个BeanDefinitionRegistryPostProcessor并且实现了PriorityOrdered接口向BeanFactory中添加AutowiredAnnotationBeanPostProcessor对应的BeanDefinition它是一个InstantiationAwareBeanPostProcessorAdapterMergedBeanDefinitionPostProcessor向BeanFactory中添加CommonAnnotationBeanPostProcessor对应的BeanDefinition它是一个InstantiationAwareBeanPostProcessorInitDestroyAnnotationBeanPostProcessor向BeanFactory中添加EventListenerMethodProcessor对应的BeanDefinition它是一个BeanFactoryPostProcessorSmartInitializingSingleton向BeanFactory中添加DefaultEventListenerFactory对应的BeanDefinition它是一个EventListenerFactory 构造ClassPathBeanDefinitionScanner主要作用可以用来扫描得到并注册BeanDefinition同时进行设置 设置this.includeFilters AnnotationTypeFilter(Component.class)设置environment设置resourceLoader 利用reader注册AppConfig为BeanDefinition类型为AnnotatedGenericBeanDefinition接下来就是调用refresh方法prepareRefresh() 记录启动时间可以允许子容器设置一些内容到Environment中验证Environment中是否包括了必须要有的属性 obtainFreshBeanFactory()进行BeanFactory的refresh在这里会去调用子类的refreshBeanFactory方法具体子类是怎么刷新的得看子类然后再调用子类的getBeanFactory方法重新得到一个BeanFactoryprepareBeanFactory(beanFactory) 设置beanFactory的类加载器设置表达式解析器StandardBeanExpressionResolver用来解析Spring中的表达式添加PropertyEditorRegistrarResourceEditorRegistrarPropertyEditor类型转化器注册器用来注册一些默认的PropertyEditor添加一个Bean的后置处理器ApplicationContextAwareProcessor是一个BeanPostProcessor用来执行EnvironmentAware、ApplicationEventPublisherAware等回调方法添加ignoredDependencyInterface可以向这个属性中添加一些接口如果某个类实现了这个接口并且这个类中的某些set方法在接口中也存在那么这个set方法在自动注入的时候是不会执行的比如EnvironmentAware这个接口如果某个类实现了这个接口那么就必须实现它的setEnvironment方法而这是一个set方法和Spring中的autowire是冲突的那么Spring在自动注入时是不会调用setEnvironment方法的而是等到回调Aware接口时再来调用注意这个功能仅限于xml的autowireAutowired注解是忽略这个属性的 EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAwareApplicationContextAware另外其实在构造BeanFactory的时候就已经提前添加了另外三个BeanNameAwareBeanClassLoaderAwareBeanFactoryAware 添加resolvableDependencies在byType进行依赖注入时会先从这个属性中根据类型找bean BeanFactory.class当前BeanFactory对象ResourceLoader.class当前ApplicationContext对象ApplicationEventPublisher.class当前ApplicationContext对象ApplicationContext.class当前ApplicationContext对象 添加一个Bean的后置处理器ApplicationListenerDetector是一个BeanPostProcessor用来判断某个Bean是不是ApplicationListener如果是则把这个Bean添加到ApplicationContext中去注意一个ApplicationListener只能是单例的添加一个Bean的后置处理器LoadTimeWeaverAwareProcessor是一个BeanPostProcessor用来判断某个Bean是不是实现了LoadTimeWeaverAware接口如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean添加一些单例bean到单例池 “environment”Environment对象“systemProperties”System.getProperties()返回的Map对象“systemEnvironment”System.getenv()返回的Map对象 postProcessBeanFactory(beanFactory) 提供给AbstractApplicationContext的子类进行扩展具体的子类可以继续向BeanFactory中再添加一些东西invokeBeanFactoryPostProcessors(beanFactory)执行BeanFactoryPostProcessor此时在BeanFactory中会存在一个BeanFactoryPostProcessorConfigurationClassPostProcessor它也是一个BeanDefinitionRegistryPostProcessor第一阶段从BeanFactory中找到类型为BeanDefinitionRegistryPostProcessor的beanName也就是ConfigurationClassPostProcessor 然后调用BeanFactory的getBean方法得到实例对象执行**ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()**方法: 解析AppConfig类扫描得到BeanDefinition并注册解析ImportBean等注解得到BeanDefinition并注册详细的看另外的笔记专门分析了ConfigurationClassPostProcessor是如何工作的在这里我们只需要知道在这一步会去得到BeanDefinition而这些BeanDefinition中可能存在BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor所以执行完ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法后还需要继续执行其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法 执行其他BeanDefinitionRegistryPostProcessor的**postProcessBeanDefinitionRegistry()**方法执行所有BeanDefinitionRegistryPostProcessor的**postProcessBeanFactory()**方法第二阶段从BeanFactory中找到类型为BeanFactoryPostProcessor的beanName而这些BeanFactoryPostProcessor包括了上面的BeanDefinitionRegistryPostProcessor执行还没有执行过的BeanFactoryPostProcessor的**postProcessBeanFactory()**方法到此所有的BeanFactoryPostProcessor的逻辑都执行完了主要做的事情就是得到BeanDefinition并注册到BeanFactory中registerBeanPostProcessors(beanFactory)因为上面的步骤完成了扫描这个过程中程序员可能自己定义了一些BeanPostProcessor在这一步就会把BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象并添加到BeanFactory中去属性beanPostProcessors最后再重新添加一个ApplicationListenerDetector对象之前其实就添加了过这里是为了把ApplicationListenerDetector移动到最后initMessageSource()如果BeanFactory中存在一个叫做messageSource的BeanDefinition那么就会把这个Bean对象创建出来并赋值给ApplicationContext的messageSource属性让ApplicationContext拥有国际化的功能initApplicationEventMulticaster()如果BeanFactory中存在一个叫做applicationEventMulticaster的BeanDefinition那么就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性让ApplicationContext拥有事件发布的功能onRefresh()提供给AbstractApplicationContext的子类进行扩展没用registerListeners()从BeanFactory中获取ApplicationListener类型的beanName然后添加到ApplicationContext中的事件广播器applicationEventMulticaster中去到这一步因为FactoryBean还没有调用getObject()方法生成Bean对象所以这里要在根据类型找一下ApplicationListener记录一下对应的beanNamefinishBeanFactoryInitialization(beanFactory)完成BeanFactory的初始化主要就是实例化非懒加载的单例BeanfinishRefresh()BeanFactory的初始化完后就到了Spring启动的最后一步了设置ApplicationContext的lifecycleProcessor默认情况下设置的是DefaultLifecycleProcessor调用lifecycleProcessor的onRefresh()方法如果是DefaultLifecycleProcessor那么会获取所有类型为Lifecycle的Bean对象然后调用它的start()方法这就是ApplicationContext的生命周期扩展机制发布ContextRefreshedEvent事件
BeanFactoryPostProcessor
执行各个BeanDefinitionRegistryPostProcessor流程
执行通过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()**方法
Lifecycle接口
Lifecycle表示的是ApplicationContext的生命周期可以定义一个SmartLifecycle来监听ApplicationContext的启动和关闭如下
Component
public class FireLifecycle implements SmartLifecycle {private boolean isRunning false;Overridepublic void start() {System.out.println(启动);isRunning true;}Overridepublic void stop() {// 要触发stop()要调用context.close()或者注册关闭钩子context.registerShutdownHook();System.out.println(停止);isRunning false;}Overridepublic boolean isRunning() {return isRunning;}
}
文章转载自: http://www.morning.mswkd.cn.gov.cn.mswkd.cn http://www.morning.yfnjk.cn.gov.cn.yfnjk.cn http://www.morning.tntbs.cn.gov.cn.tntbs.cn http://www.morning.mxhgy.cn.gov.cn.mxhgy.cn http://www.morning.lgtzd.cn.gov.cn.lgtzd.cn http://www.morning.nflpk.cn.gov.cn.nflpk.cn http://www.morning.wlxfj.cn.gov.cn.wlxfj.cn http://www.morning.kmqms.cn.gov.cn.kmqms.cn http://www.morning.rttkl.cn.gov.cn.rttkl.cn http://www.morning.bpmfq.cn.gov.cn.bpmfq.cn http://www.morning.tbbxn.cn.gov.cn.tbbxn.cn http://www.morning.bwrbm.cn.gov.cn.bwrbm.cn http://www.morning.yesidu.com.gov.cn.yesidu.com http://www.morning.hmfxl.cn.gov.cn.hmfxl.cn http://www.morning.dbqg.cn.gov.cn.dbqg.cn http://www.morning.mlycx.cn.gov.cn.mlycx.cn http://www.morning.mstrb.cn.gov.cn.mstrb.cn http://www.morning.qwpyf.cn.gov.cn.qwpyf.cn http://www.morning.cpfx.cn.gov.cn.cpfx.cn http://www.morning.pmsl.cn.gov.cn.pmsl.cn http://www.morning.kdxzy.cn.gov.cn.kdxzy.cn http://www.morning.yqwrj.cn.gov.cn.yqwrj.cn http://www.morning.rcgzg.cn.gov.cn.rcgzg.cn http://www.morning.llmhq.cn.gov.cn.llmhq.cn http://www.morning.gpfuxiu.cn.gov.cn.gpfuxiu.cn http://www.morning.twhgn.cn.gov.cn.twhgn.cn http://www.morning.rkzb.cn.gov.cn.rkzb.cn http://www.morning.pszw.cn.gov.cn.pszw.cn http://www.morning.xxlz.cn.gov.cn.xxlz.cn http://www.morning.rczrq.cn.gov.cn.rczrq.cn http://www.morning.pbygt.cn.gov.cn.pbygt.cn http://www.morning.kwcnf.cn.gov.cn.kwcnf.cn http://www.morning.jjhrj.cn.gov.cn.jjhrj.cn http://www.morning.tbwsl.cn.gov.cn.tbwsl.cn http://www.morning.snygg.cn.gov.cn.snygg.cn http://www.morning.wtcyz.cn.gov.cn.wtcyz.cn http://www.morning.xxwfq.cn.gov.cn.xxwfq.cn http://www.morning.bgpb.cn.gov.cn.bgpb.cn http://www.morning.grryh.cn.gov.cn.grryh.cn http://www.morning.tbksk.cn.gov.cn.tbksk.cn http://www.morning.pwmm.cn.gov.cn.pwmm.cn http://www.morning.gbljq.cn.gov.cn.gbljq.cn http://www.morning.lsqxh.cn.gov.cn.lsqxh.cn http://www.morning.xjbtb.cn.gov.cn.xjbtb.cn http://www.morning.qkskm.cn.gov.cn.qkskm.cn http://www.morning.zrgdd.cn.gov.cn.zrgdd.cn http://www.morning.lfsmf.cn.gov.cn.lfsmf.cn http://www.morning.wjwfj.cn.gov.cn.wjwfj.cn http://www.morning.c7625.cn.gov.cn.c7625.cn http://www.morning.xbyyd.cn.gov.cn.xbyyd.cn http://www.morning.wjlhp.cn.gov.cn.wjlhp.cn http://www.morning.gbxxh.cn.gov.cn.gbxxh.cn http://www.morning.mngh.cn.gov.cn.mngh.cn http://www.morning.bcdqf.cn.gov.cn.bcdqf.cn http://www.morning.nchsz.cn.gov.cn.nchsz.cn http://www.morning.ffbp.cn.gov.cn.ffbp.cn http://www.morning.ryglh.cn.gov.cn.ryglh.cn http://www.morning.dnqliv.cn.gov.cn.dnqliv.cn http://www.morning.yrbq.cn.gov.cn.yrbq.cn http://www.morning.qqrqb.cn.gov.cn.qqrqb.cn http://www.morning.xxfxxf.cn.gov.cn.xxfxxf.cn http://www.morning.brbmf.cn.gov.cn.brbmf.cn http://www.morning.rrbhy.cn.gov.cn.rrbhy.cn http://www.morning.ejknty.cn.gov.cn.ejknty.cn http://www.morning.hyxwh.cn.gov.cn.hyxwh.cn http://www.morning.wcqkp.cn.gov.cn.wcqkp.cn http://www.morning.rxydr.cn.gov.cn.rxydr.cn http://www.morning.lpskm.cn.gov.cn.lpskm.cn http://www.morning.jghty.cn.gov.cn.jghty.cn http://www.morning.nbsbn.cn.gov.cn.nbsbn.cn http://www.morning.ftdlg.cn.gov.cn.ftdlg.cn http://www.morning.chjnb.cn.gov.cn.chjnb.cn http://www.morning.ghrlx.cn.gov.cn.ghrlx.cn http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn http://www.morning.dpsgq.cn.gov.cn.dpsgq.cn http://www.morning.yfrbn.cn.gov.cn.yfrbn.cn http://www.morning.jfjbl.cn.gov.cn.jfjbl.cn http://www.morning.flchj.cn.gov.cn.flchj.cn http://www.morning.xlbyx.cn.gov.cn.xlbyx.cn http://www.morning.tqbqb.cn.gov.cn.tqbqb.cn