往期博客:

《Spring源码深度解析 郝佳 第2版》容器的基本实现与XML文件的加载

《Spring源码深度解析 郝佳 第2版》XML标签的解析

《Spring源码深度解析 郝佳 第2版》bean的加载、循环依赖的解决

往期博客分析了BeanFactory接口以及他的默认实现类XmlBeanFactory

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));

接下来分析另外一个高级拓展接口ApplicationContext,以它加载xml文件为例分析

 // ClassPathXmlApplicationContext 继承 ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("sichaolong.xml");

目录

  1. 入口ClassPathXmlApplicationContext

    • 将配置文件路径数组保存到AbstractRefreshableApplicationContext的成员变量configLocations
    • 完成配置文件加载解析及容器核心功能,调用AbstractApplicationContetxt的refresh()
  2. 核心AbstractApplicationContetxt的refresh()的流程分析

    • // 准备刷新上下文环境this.prepareRefresh();
    • // 初始化BeanFactory并进行xml文件读取ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
    • // 对BeanFactory的各种功能填充this.prepareBeanFactory(beanFactory);
    • // 空实现,由子类覆盖重写拓展this.postProcessBeanFactory(beanFactory);
    • // 激活各种BeanFactory处理器this.invokeBeanFactoryPostProcessors(beanFactory);
    • // 注册拦截Bean创建的处理器,真正调用在getBean()时候this.registerBeanPostProcessors(beanFactory);
    • // 为上下文初始化国际化处理this.initMessageSource();
    • // 为上下文初始化应用消息广播器,放入applicationEventMulticast类型的bean中this.initApplicationEventMulticaster();
    • // 留给子类初始化其他的beanthis.onRefresh();
    • // 在注册bean中查找Listener bean,注册到8的应用上下文广播器this.registerListeners();
    • // 初始化剩下的单实例 this.finishBeanFactoryInitialization(beanFactory);
    • // 完成刷新过程,通知生命周期管理器lifecycleProcessor刷新过程this.finishRefresh();
  3. SpringBoot的run()方法

    • // 启动类注解
    • // run方法

一、入口ClassPathXmlApplicationContext

实例化ClassPathXmlApplicationContext传入xml配置文件的路径,可以传入多个路径

// 1. 将配置文件路径保存在AbstractRefreshableApplicationContext的成员变量configLocations

// 2. 对于数组路径的解析加载以及功能实现都在AbstractApplicationContext的refresh()

// ClassPathXmlApplication 构造方法
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[]{configLocation}, true, (ApplicationContext)null);}
// 重载
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {// 初始化父类容器super(parent);// 1. 解析传入的路径数组,调用reslovePath(),保存到成员变量AbstractRefreshableApplicationContext的configLocationsthis.setConfigLocations(configLocations);if (refresh) {// 2. xml解析及容器功能实现,调用AbstractAplicationContext#refresh()this.refresh();}}

// 1. 解析传入的路径数组,调用reslovePath(),保存到成员变量AbstractRefreshableApplicationContext的configLocations

public void setConfigLocations(@Nullable String... locations) {if (locations != null) {Assert.noNullElements(locations, "Config locations must not be null");this.configLocations = new String[locations.length];for(int i = 0; i < locations.length; ++i) {this.configLocations[i] = this.resolvePath(locations[i]).trim();}} else {this.configLocations = null;}}

// 2. 功能实现AbstractAplicationContext#refresh()

 public void refresh() throws BeansException, IllegalStateException {synchronized(this.startupShutdownMonitor) {// 1. 准备刷新上下文环境this.prepareRefresh();// 2. 初始化BeanFactory并进行xml文件读取ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();// 3. 对BeanFactory的各种功能填充this.prepareBeanFactory(beanFactory);try {// 4. 空实现,由子类覆盖重写拓展this.postProcessBeanFactory(beanFactory);// 5. 激活各种BeanFactory处理器this.invokeBeanFactoryPostProcessors(beanFactory);// 6. 注册拦截Bean创建的处理器,真正调用在getBean()时候this.registerBeanPostProcessors(beanFactory);// 7. 为上下文初始化国际化处理this.initMessageSource();// 8. 为上下文初始化应用消息广播器,放入applicationEventMulticast类型的bean中this.initApplicationEventMulticaster();// 9. 留给子类初始化其他的beanthis.onRefresh();// 10. 在注册bean中查找Listener bean,注册到8的应用上下文广播器this.registerListeners();// 11. 初始化剩下的单实例this.finishBeanFactoryInitialization(beanFactory);// 12. 完成刷新过程,通知生命周期管理器lifecycleProcessor刷新过程this.finishRefresh();} catch (BeansException var9) {if (this.logger.isWarnEnabled()) {this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);}this.destroyBeans();this.cancelRefresh(var9);throw var9;} finally {this.resetCommonCaches();}}}

二、核心AbstractApplicationContetxt的refresh()的流程分析

// 1. 准备刷新上下文环境 this.prepareRefresh();

主要是初始化前的准备工作,如对系统属性和环境变量的准备验证,留了两个模板空实现,需要我们自己写XxxApplicationContext继承ApplicationContext接口重写方法使用

// AbstractApplicationContextprotected void prepareRefresh() {// 开始时间this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (this.logger.isDebugEnabled()) {if (this.logger.isTraceEnabled()) {this.logger.trace("Refreshing " + this);} else {this.logger.debug("Refreshing " + this.getDisplayName());}}// 空实现,留给子类实现this.initPropertySources();// 空实现,验证需要的属性文件都以否放入环境中,可以重写自定义规则,如getEnvironment().setRequiredProperties("xiaosi")this.getEnvironment().validateRequiredProperties();if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet(this.applicationListeners);} else {this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}this.earlyApplicationEvents = new LinkedHashSet();}

// 2. 初始化BeanFactory并进行xml文件读取ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

// AbstractApplicationContext
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {this.refreshBeanFactory();return this.getBeanFactory();}
// 委托 AbstractRefreshableApplicationContextprotected final void refreshBeanFactory() throws BeansException {if (this.hasBeanFactory()) {this.destroyBeans();this.closeBeanFactory();}try {// 2.1 创建 DefaultListableBeanFactoryDefaultListableBeanFactory beanFactory = this.createBeanFactory();// 序列化idbeanFactory.setSerializationId(this.getId());// 2.2 定制beanFactory,设置属性包括是否允许覆盖同名不同定义对象,是否允许循环依赖// 在书中说这里设置@Autowired、@Qualifier注解解析器QualifierAnnotationAutowireCondiateResolver,但是我看的SpringBoot 2.3.7版本已经无此设置this.customizeBeanFactory(beanFactory);// 2.3 加载BeanDefinitions,初始化DoucmentLoader读取解析xmlthis.loadBeanDefinitions(beanFactory);// 2.4 使用全局变量记录BeanFactory实例this.beanFactory = beanFactory;} catch (IOException var2) {throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var2);}}// 2.2 AbstractRefreshableApplicationContext#customizeBeanFactory()
// 依旧是模板方法留给子类覆盖设置这两个属性
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {if (this.allowBeanDefinitionOverriding != null) {beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.allowCircularReferences != null) {beanFactory.setAllowCircularReferences(this.allowCircularReferences);}}

// 对2.2的补充,SpringBoot 2.3.7版本下直接使用的是SimpleAutowirdCandiateResolver解析@Autowired、@Qualifier,具体实现类是QualifierAnnotationAutowireCondiateResolver,即默认采用autowireByType方式注入



// 2.3 委托AbstractXmlApplication初始化XmlBeanDefinitionReader老loadBeanDefinitions(),解析configLocations下保存的xml数组路径,初始化DoucmentLoader读取。经过此步,XmlBeanDefinitionReader解析出来的BeanDefinitionHolder已经保存到DefaultListableBeanFactory。此时ApplicationContext已经拿到了BeanFactory的所有解析的好配置

// AbstractXmlApplication初始化XmlBeanDefinitionReader
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);beanDefinitionReader.setEnvironment(this.getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// 初始化beanDefinitionReaderthis.initBeanDefinitionReader(beanDefinitionReader);// 解析AbstractRefreshableApplicationContext成员变量configLocations,也就是xml配置文件路径数组this.loadBeanDefinitions(beanDefinitionReader);}
// AbstractXmlApplication使用XmlBeanDefinitionReader 解析xml
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {Resource[] configResources = this.getConfigResources();if (configResources != null) {reader.loadBeanDefinitions(configResources);}String[] configLocations = this.getConfigLocations();if (configLocations != null) {// 解析,接着就是到AbstractBeanDefinitionReader,reader就是之前BeanFactory的那一套XmlBeanDefinitionReaderreader.loadBeanDefinitions(configLocations);}}

// 3. 对BeanFactory的各种功能填充this.prepareBeanFactory(beanFactory);

上面已经完成BeanFactory配置文件解析和保存,此步开始就是ApplicationContext拓展功能的实现

// AbsractApplicationContext对DefaultListableBeanFactory进行功能拓展
// DefaultListableBeanFactory 继承 ConfigurableListableBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 3.1 设置类加载器beanFactory.setBeanClassLoader(this.getClassLoader());// 3.2 增加支持#{bean.xxx}形式取值,即SpEL表达式//在bean初始化之后的属性填充,会调用AbstractAutowireCapableBeanFactory了的applyPropertyValues函数来完成功能// 就在这个函数中会构造BeanDefinitionValueResolver类型的valueRsolver来进行属性取值// 一般会通过AbstractBeanFactory的evaluateBeanDefinitionString方法完成SpEL的解析// 总结:就是在bean的依赖填充、属性填充的时候会用到应用语言解析器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 3.3 增加PropertyEditor工具方便对bean的属性管理,// 如在xml中配置String类型的日期,解析到Bean的Date类型属性可能会报错// 解决办法就是自己定义一个PropertyEditor工具,创建XxxPropertyEditor继承PropertyEditorSupport重写setAsText实现自定义规则,然后放到容器中beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));// 3.4 添加BeanPostProcessor处理器beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 3.5 忽略几个自动装配的接口,因为实现了XxxAware接口可以自动获取Xxx,不需要自动注入装配// 实现了XxxAware的bean在初始化前、实例化后会调用postProcessBeforeInitialization()完成需要的属性装配// 详情看3.4添加的BeanPostProcessor处理器beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// 3.6 设置几个自动装配的规则beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// 3.7 增加对AspestJ的支持,静态AOPif (beanFactory.containsBean("loadTimeWeaver")) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// 3.8 添加默认的系统环境Bean,当我们的bean需要下列bean的时候可以直接拿到if (!beanFactory.containsLocalBean("environment")) {beanFactory.registerSingleton("environment", this.getEnvironment());}if (!beanFactory.containsLocalBean("systemProperties")) {beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean("systemEnvironment")) {beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());}}

// 3.4 添加BeanPostProcessor处理器

在bean实例化前后会调用BeanPostProcessor的postProcessBeforeInitialization()和postProcessAfterInitialization(),后置处理默认为空

主要是前置处理,主要做的工作是对那些实现了XxxAware的bean在初始化后、实例化前会获得对应的资源,因此下面会忽略几个XxxAware的自动装配

// ApplicationContextAwareProcessor实现BeanPostProcessor
// 实例化前处理@Nullablepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (!(bean instanceof EnvironmentAware) && !(bean instanceof EmbeddedValueResolverAware) && !(bean instanceof ResourceLoaderAware) && !(bean instanceof ApplicationEventPublisherAware) && !(bean instanceof MessageSourceAware) && !(bean instanceof ApplicationContextAware)) {return bean;} else {AccessControlContext acc = null;if (System.getSecurityManager() != null) {acc = this.applicationContext.getBeanFactory().getAccessControlContext();}if (acc != null) {AccessController.doPrivileged(() -> {// 调用this.invokeAwareInterfaces(bean);return null;}, acc);} else {// 调用this.invokeAwareInterfaces(bean);}return bean;}}// 实现了这些Aware的接口的bean在初始化后、实例化前可以获取一些资源private void invokeAwareInterfaces(Object bean) {if (bean instanceof EnvironmentAware) {((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware)bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);}}

// 4. 空实现,由子类覆盖重写拓展this.postProcessBeanFactory(beanFactory);

4.1 作用

BeanFactoryPostProcessor和BeanPostProcessor类似,允许beanFactory容器在实例化任何其他bean的时候对bean统一的增强或修改,允许多个实现了Ordered接口的PostProcessBeanFactory来依次处理,他的范围是容器级的,不能跨容器,如果对bean的处理,最好还是使
用BeanPostPrecessor。

4.2 加载Properties文件的原理

具体应用就是PropertyPlaceholderConfigurer,他支持在xml配置文件使用 ${myPropertoes.msg}来从myProperties.properties文件取值。依靠在xml中配置PropertyPlaceholderConfigurer类型的bean,并在<property>标签指定myProperties.properties文件的地址。原理就是PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessor接口,在容器启动读取所有bean配置文件之后、bean初始化之前,会执行postPrecessBeanFactory()方法,该方法内会依次执行mergeProperties()、convertProperties()、processProperties()这三个方法读取properties内容到beanFactory

// 5. 激活各种BeanFactory处理器 this.invokeBeanFactoryPostProcessors(beanFactory);

在上面说明了BeanFactoryPostProcessor的用处,接下来需要知道这些处理器是怎么被激活的。

// AbstarctApplicationContext
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 委托PostProcessorRegistrationDelegate的静态方法PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}

// 委托PostProcessorRegistrationDelegate的静态方法进行BeanFactoryPostProcessor的激活,主要是两类

  • 激活BeanDefinitionRegistry
  • 激活普通的BeanFactoryPostProcessor
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// 存放的BeanFactoryPostProcessor集合Set<String> processedBeans = new HashSet();ArrayList regularPostProcessors;ArrayList registryProcessors;int var9;ArrayList currentRegistryProcessors;String[] postProcessorNames;// 1. 第一类 BeanDefinitionRegistryif (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;// 存放第二类常规硬编码的BeanFactoryPostProcessorsregularPostProcessors = new ArrayList();// 存放第一类硬编码BeanDefinitionRegistryregistryProcessors = new ArrayList();// 遍历全部Iterator var6 = beanFactoryPostProcessors.iterator();while(var6.hasNext()) {BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();// 第一类注册及添加硬编码registryProcessors 集合if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);} else {// 第二类添加硬编码regularPostProcessors 集合regularPostProcessors.add(postProcessor);}}currentRegistryProcessors = new ArrayList();postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);String[] var16 = postProcessorNames;var9 = postProcessorNames.length;int var10;String ppName;for(var10 = 0; var10 < var9; ++var10) {ppName = var16[var10];if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);var16 = postProcessorNames;var9 = postProcessorNames.length;for(var10 = 0; var10 < var9; ++var10) {ppName = var16[var10];if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}// 第二类,普通的BeanFactoryPostProcessorsortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();boolean reiterate = true;while(reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);String[] var19 = postProcessorNames;var10 = postProcessorNames.length;for(int var26 = 0; var26 < var10; ++var26) {String ppName = var19[var26];if (!processedBeans.contains(ppName)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);reiterate = true;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);currentRegistryProcessors.clear();}invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);} else {invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);}String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);regularPostProcessors = new ArrayList();registryProcessors = new ArrayList();currentRegistryProcessors = new ArrayList();postProcessorNames = postProcessorNames;int var20 = postProcessorNames.length;String ppName;for(var9 = 0; var9 < var20; ++var9) {ppName = postProcessorNames[var9];if (!processedBeans.contains(ppName)) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {registryProcessors.add(ppName);} else {currentRegistryProcessors.add(ppName);}}}sortPostProcessors(regularPostProcessors, beanFactory);invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(registryProcessors.size());Iterator var21 = registryProcessors.iterator();while(var21.hasNext()) {String postProcessorName = (String)var21.next();orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());Iterator var24 = currentRegistryProcessors.iterator();while(var24.hasNext()) {ppName = (String)var24.next();nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);beanFactory.clearMetadataCache();}

// 6. 注册拦截Bean创建的处理器,真正调用在getBean()时候this.registerBeanPostProcessors(beanFactory);

此步注册BeanPostProcessors,真正进行bean初始化之前会调用

在beanFactory等容器的时候因为没有实现后处理器的自动注册,因此需要用户手动注册才能使用,但是在ApplicationContext中,已经自动注册了如InstationAwareBeanPostProcessor,所以我们在xml中配置了实现了InstationAwareBeanPostProcessor的bean并重写了postProcessBeforeInstation等方法之后,就会对bean初始化、实例化前后进行处理。

// AbstractApplicationContext
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 委托PostProcessorRegistrationDelegate的静态方法PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}

// 配置的BeanPostProcessor可以分为四类

  • 实现了PriorityOrdered的BeanPostProcessor
  • 实现了Ordered的BeanPostProcessor
  • 所有无序的BeanPostProcessor
  • 所有MergerdBeanDefinitionPostProcessor,并排除重复注册
// // 委托PostProcessorRegistrationDelegate的静态方法进行BeanPostProcessor处理器的注册
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// 实现了PriorityOrdered的BeanPostProcessorList<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();List<BeanPostProcessor> internalPostProcessors = new ArrayList();// 实现了Ordered的BeanPostProcessorList<String> orderedPostProcessorNames = new ArrayList();// 所有无序的BeanPostProcessorList<String> nonOrderedPostProcessorNames = new ArrayList();String[] var8 = postProcessorNames;int var9 = postProcessorNames.length;String ppName;BeanPostProcessor pp;for(int var10 = 0; var10 < var9; ++var10) {ppName = var8[var10];if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);} else {nonOrderedPostProcessorNames.add(ppName);}}// 第一类,排序注册sortPostProcessors(priorityOrderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);List<BeanPostProcessor> orderedPostProcessors = new ArrayList(orderedPostProcessorNames.size());Iterator var14 = orderedPostProcessorNames.iterator();while(var14.hasNext()) {String ppName = (String)var14.next();BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}// 第二类,排序注册sortPostProcessors(orderedPostProcessors, beanFactory);registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList(nonOrderedPostProcessorNames.size());Iterator var17 = nonOrderedPostProcessorNames.iterator();while(var17.hasNext()) {ppName = (String)var17.next();pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}// 第三类,排序注册registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);sortPostProcessors(internalPostProcessors, beanFactory);// 第四类,注册registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);// 添加ApplicationListener探测器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}
// 注册
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {Iterator var2 = postProcessors.iterator();while(var2.hasNext()) {BeanPostProcessor postProcessor = (BeanPostProcessor)var2.next();// 委托AbstarctApplicationContextbeanFactory.addBeanPostProcessor(postProcessor);}}
// 委托AbstarctApplicationContext
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");// 防止重复this.beanPostProcessors.remove(beanPostProcessor);if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {this.hasInstantiationAwareBeanPostProcessors = true;}if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {this.hasDestructionAwareBeanPostProcessors = true;}this.beanPostProcessors.add(beanPostProcessor);}

// 7. 为上下文初始化国际化处理this.initMessageSource();

// 8. 为上下文初始化应用消息广播器,放入applicationEventMulticast类型的bean中this.initApplicationEventMulticaster();

先看看事件监听的用法,需要定义

  • 实现ApplicationEvent定义监听事件
  • 实现ApplicationListener定义监听器,重写onApplicationEvent方法根据形参ApplicationEvent处理事件
  • 添加配置文件,将时间监听器通过xml放到容器
  • 测试,创建事件实例,使用ApplicationContext实例调用publishEvent()事件

类似观察者模式,可以在比较关心的事件发生之后及时的处理

// AbstractApplicationContext
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();// 判断本地有无自定义的事件广播器,有就使用自定义的if (beanFactory.containsLocalBean("applicationEventMulticaster")) {this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);if (this.logger.isTraceEnabled()) {this.logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}} else {// 使用默认的事件广播器 SimpleApplicationEventMulticasterthis.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);if (this.logger.isTraceEnabled()) {this.logger.trace("No 'applicationEventMulticaster' bean, using [" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");}}}
// SimpleApplicationEventMulticaster的multicastEvent// 当发生Spring事件,SimpleApplicationEventMulticaster会调用multicastEvent广播事件
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);Executor executor = this.getTaskExecutor();Iterator var5 = this.getApplicationListeners(event, type).iterator();while(var5.hasNext()) {ApplicationListener<?> listener = (ApplicationListener)var5.next();if (executor != null) {executor.execute(() -> {// 唤醒listenersthis.invokeListener(listener, event);});} else {this.invokeListener(listener, event);}}}

// 9. 留给子类初始化其他的bean模板this.onRefresh();

主要实现类有

// 10. 在注册bean中查找Listener bean,注册到8的应用上下文广播器this.registerListeners();

// AbstractApplicationContextprotected void registerListeners() {Iterator var1 = this.getApplicationListeners().iterator();// 硬编码监听器注册while(var1.hasNext()) {ApplicationListener<?> listener = (ApplicationListener)var1.next();this.getApplicationEventMulticaster().addApplicationListener(listener);}// 通过配置文件配置的监听器注册String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);String[] var7 = listenerBeanNames;int var3 = listenerBeanNames.length;for(int var4 = 0; var4 < var3; ++var4) {String listenerBeanName = var7[var4];this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;this.earlyApplicationEvents = null;if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {Iterator var9 = earlyEventsToProcess.iterator();while(var9.hasNext()) {ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();this.getApplicationEventMulticaster().multicastEvent(earlyEvent);}}}

// 11. 初始化剩下的单实例this.finishBeanFactoryInitialization(beanFactory);

完成BeanFactory的初始化工作,其中包括

  • ConversionService的设置:自定义XxxConvert实现Convert<oldType,newType> 接口,重写convert方法,返回newType。然后注册ConvertService类型的bean设置<property><list>MyConvert</list></property>。然后测试,创建DefultConversionService实例,addService(new MyConvert()),然后调用convert方法返回需要的newType
  • 配置冻结:synchronized锁住beanDefinitionMap
  • 初始化非延迟加载单例bean:ApplicationContext实现的默认行为是在启动的时候将所有的单例bean提前委托DefaultListabelBeanFactory进行实例化,意味着bean的实例化和容器的初始化为一个过程,通常这是一个好事,因为在配置bean过程中的错误会被立即发现。
// AbstractApplicationContext// ConversionService的设置,类似之前自定义转换器从String转为Date的方式
// 在Spring还有另外一种方式,也就是使用Convertprotected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));}if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver((strVal) -> {return this.getEnvironment().resolvePlaceholders(strVal);});}// AspectJ 静态AOP配置String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);String[] var3 = weaverAwareNames;int var4 = weaverAwareNames.length;for(int var5 = 0; var5 < var4; ++var5) {String weaverAwareName = var3[var5];this.getBean(weaverAwareName);}beanFactory.setTempClassLoader((ClassLoader)null);// 冻结所有的bean定义,说明注册的bean定义将不被修改或任何一步的改变beanFactory.freezeConfiguration();// 初始化剩下的单实例(非惰性)beanFactory.preInstantiateSingletons();}
// DefaultListableBeanFactorypublic void preInstantiateSingletons() throws BeansException {if (this.logger.isTraceEnabled()) {this.logger.trace("Pre-instantiating singletons in " + this);}List<String> beanNames = new ArrayList(this.beanDefinitionNames);Iterator var2 = beanNames.iterator();while(true) {String beanName;Object bean;do {while(true) {RootBeanDefinition bd;do {do {do {if (!var2.hasNext()) {var2 = beanNames.iterator();while(var2.hasNext()) {beanName = (String)var2.next();Object singletonInstance = this.getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged(() -> {smartSingleton.afterSingletonsInstantiated();return null;}, this.getAccessControlContext());} else {smartSingleton.afterSingletonsInstantiated();}}}return;}beanName = (String)var2.next();bd = this.getMergedLocalBeanDefinition(beanName);} while(bd.isAbstract());} while(!bd.isSingleton());} while(bd.isLazyInit());if (this.isFactoryBean(beanName)) {bean = this.getBean("&" + beanName);break;}this.getBean(beanName);}} while(!(bean instanceof FactoryBean));FactoryBean<?> factory = (FactoryBean)bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {SmartFactoryBean var10000 = (SmartFactoryBean)factory;((SmartFactoryBean)factory).getClass();isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());} else {isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();}if (isEagerInit) {this.getBean(beanName);}}}

// 12. 完成刷新过程,通知生命周期管理器lifecycleProcessor刷新过程this.finishRefresh();

在Spring中提供了Liftcycle接口,主要用于生命周期相关,Liftcycle包含strart、stop方法

// AbstractApplicationContext
protected void finishRefresh() {this.clearResourceCaches();// 1. 在ApplicationContext启动或者停止的时候会通过ListcycleProcessor对所有声明的bean周期做状态更新,需要先初始化它this.initLifecycleProcessor();// 2. 启动所有实现了Listcycle接口的beanthis.getLifecycleProcessor().onRefresh();// 3. 发布启动成功的事件this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));LiveBeansView.registerApplicationContext(this);}// 1. 在ApplicationContext启动或者停止的时候会通过ListcycleProcessor对所有声明的bean周期做状态更新,需要先初始化它
protected void initLifecycleProcessor() {ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();if (beanFactory.containsLocalBean("lifecycleProcessor")) {this.lifecycleProcessor = (LifecycleProcessor)beanFactory.getBean("lifecycleProcessor", LifecycleProcessor.class);if (this.logger.isTraceEnabled()) {this.logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");}} else {DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();defaultProcessor.setBeanFactory(beanFactory);this.lifecycleProcessor = defaultProcessor;beanFactory.registerSingleton("lifecycleProcessor", this.lifecycleProcessor);if (this.logger.isTraceEnabled()) {this.logger.trace("No 'lifecycleProcessor' bean, using [" + this.lifecycleProcessor.getClass().getSimpleName() + "]");}}}// 2. 启动所有实现了Listcycle接口的bean// DefaultLifecycleProcessorpublic void onRefresh() {this.startBeans(true);this.running = true;}private void startBeans(boolean autoStartupOnly) {Map<String, Lifecycle> lifecycleBeans = this.getLifecycleBeans();Map<Integer, DefaultLifecycleProcessor.LifecycleGroup> phases = new HashMap();lifecycleBeans.forEach((beanName, bean) -> {if (!autoStartupOnly || bean instanceof SmartLifecycle && ((SmartLifecycle)bean).isAutoStartup()) {int phase = this.getPhase(bean);DefaultLifecycleProcessor.LifecycleGroup group = (DefaultLifecycleProcessor.LifecycleGroup)phases.get(phase);if (group == null) {group = new DefaultLifecycleProcessor.LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);phases.put(phase, group);}group.add(beanName, bean);}});if (!phases.isEmpty()) {List<Integer> keys = new ArrayList(phases.keySet());Collections.sort(keys);Iterator var5 = keys.iterator();while(var5.hasNext()) {Integer key = (Integer)var5.next();// 启动((DefaultLifecycleProcessor.LifecycleGroup)phases.get(key)).start();}}}

三、SpringBoot的run()方法

启动类

// 1. 启动类注解
@SpringBootApplication
public class StudySpringApplication {public static void main(String[] args) {// 2. run()方法SpringApplication.run(StudySpringApplication.class, args);}}

// 1. 启动类注解

package org.springframework.boot.autoconfigure;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited@SpringBootConfiguration // 配置类
@EnableAutoConfiguration // 自动装配
// 包扫描
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {@AliasFor(annotation = EnableAutoConfiguration.class)Class<?>[] exclude() default {};@AliasFor(annotation = EnableAutoConfiguration.class)String[] excludeName() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")String[] scanBasePackages() default {};@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")Class<?>[] scanBasePackageClasses() default {};@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;}

// 2. run方法

// 入口

 public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {//primarySource为 StudySpringApplication.classreturn run(new Class[]{primarySource}, args);}
// 重载
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {return (new SpringApplication(primarySources)).run(args);}// 构造函数
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.sources = new LinkedHashSet();// 图标模式this.bannerMode = Mode.CONSOLE;this.logStartupInfo = true;this.addCommandLineProperties = true;// 转换器this.addConversionService = true;this.headless = true;this.registerShutdownHook = true;this.additionalProfiles = new HashSet();this.isCustomEnvironment = false;this.lazyInitialization = false;this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));// web容器类型this.webApplicationType = WebApplicationType.deduceFromClasspath();this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = this.deduceMainApplicationClass();}
// web容器类型,根据ClassPath判断,设置成员变量webApplicationType
static WebApplicationType deduceFromClasspath() {if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {return REACTIVE;} else {String[] var0 = SERVLET_INDICATOR_CLASSES;int var1 = var0.length;for(int var2 = 0; var2 < var1; ++var2) {String className = var0[var2];if (!ClassUtils.isPresent(className, (ClassLoader)null)) {return NONE;}}return SERVLET;}}

// 重载

public ConfigurableApplicationContext run(String... args) {// 1. 计时器StopWatch stopWatch = new StopWatch();stopWatch.start();// 2. 容器ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();this.configureHeadlessProperty();SpringApplicationRunListeners listeners = this.getRunListeners(args);listeners.starting();Collection exceptionReporters;try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 3.准备环境,根据webApplicationType 准备上下文环境// webApplicationType 是在构造函数时根据ClassPath下内容设置的ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);this.configureIgnoreBeanInfo(environment);Banner printedBanner = this.printBanner(environment);// 4. 创建容器,根据webApplicationType给contextClass赋值,然后初始化对应上下文容器context = this.createApplicationContext();exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);// 5. 准备容器相关this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);// 6. 刷新容器,这里委托ConfigurableApplicationContext接口的refesh(),// 真实调用的是AbstractApplicationContext.refresh(),也就是上面分析的部分this.refreshContext(context);this.afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);}listeners.started(context);this.callRunners(context, applicationArguments);} catch (Throwable var10) {this.handleRunFailure(context, var10, exceptionReporters, listeners);throw new IllegalStateException(var10);}try {listeners.running(context);return context;} catch (Throwable var9) {this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);throw new IllegalStateException(var9);}}
// 2.3 根据webApplicationType 准备环境prepareEnvironment()

// 准备环境,根据webApplicationType 准备上下文环境

// webApplicationType 是在构造函数时根据ClassPath下内容设置的,主要作用是判断是web服务还是一般的boot服务,来创建对用的上下文ApplicationContext

 private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {// 1. 获取ClassPath下的当前上下文环境,方法内部给根据成员变量webApplicationType赋值// 有SERVLET、NONE、REACTIVE等,下面会对比是否添加web-starter的DebugConfigurableEnvironment environment = this.getOrCreateEnvironment();this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());ConfigurationPropertySources.attach((Environment)environment);listeners.environmentPrepared((ConfigurableEnvironment)environment);this.bindToSpringApplication((ConfigurableEnvironment)environment);if (!this.isCustomEnvironment) {environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());}ConfigurationPropertySources.attach((Environment)environment);return (ConfigurableEnvironment)environment;}// 1. 调用方法根据 在构造函数执行的时候根据ClassPath设置了成员变量webApplicationType
private ConfigurableEnvironment getOrCreateEnvironment() {if (this.environment != null) {return this.environment;} else {switch(this.webApplicationType) {case SERVLET:return new StandardServletEnvironment();case REACTIVE:return new StandardReactiveWebEnvironment();default:return new StandardEnvironment();}}}
// Debug prepareEnvironment() :pom依赖有web-starter,观察webApplicationType的值为枚举类值SERVLET

// Debug prepareEnvironment() :pom依赖无web-starter,观察webApplicationType的值为枚举类值NONE


总结:

  • 有web服务情况下上下文Environment为StandardServletEnvironment。
  • 无web服务的情况下上下文Environment为StandardEnvironment。
// 2.4. 创建容器context = this.createApplicationContext();

根据成员变量判断创建那种ApplicationContext,即根据Environmet的值先给成员变量contextClass赋值

然后return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);创建ApplicationContext上下文


private Class<? extends ConfigurableApplicationContext> applicationContextClass;protected ConfigurableApplicationContext createApplicationContext() {Class<?> contextClass = this.applicationContextClass;if (contextClass == null) {try {switch(this.webApplicationType) {// 有web的默认上下文case SERVLET:contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");break;case REACTIVE:contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");break;// 没有web的默认上下文default:contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");}} catch (ClassNotFoundException var3) {throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);}}return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);}
// Debug createApplicationContext():pom有web-starter,观察contextClass的值为AnnotationConfigServletWebServerApplicationContext


// Debug createApplicationContext():pom无web-starter,观察contextClass的值为AnnotationConfigApplicationContext


总结:

  • 有web服务情况下上下文Environment为StandardServletEnvironment。上下文为AnnotationConfigServletWebServerApplicationContext
  • 无web服务的情况下上下文Environment为StandardEnvironment。上下文为AnnotationConfigApplicationContext
// 2.6. 刷新容器,这里委托ConfigurableApplicationContext接口的refesh(),真实调用的是AbstractApplicationContext.refresh(),也就是上面分析的部分this.refreshContext(context);

《Spring源码深度解析 郝佳 第2版》ApplicationContext相关推荐

  1. Spring学习总结(7)——applicationContext.xml 配置文详解

    web.xml中classpath:和classpath*:  有什么区别? classpath:只会到你的class路径中查找找文件; classpath*:不仅包含class路径,还包括jar文件 ...

  2. 为什么大多数IOC容器使用ApplicationContext,而不用BeanFactory

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 1. 引言 Spring框架附带了两个IOC容器– Bea ...

  3. springMVC 使用WebApplicationContext获取ApplicationContext对象

    主要用于从application中获取bean 1.applicationContext 在web.xml中使用listener配置 <context-param><param-na ...

  4. spring获取webapplicationcontext,applicationcontext几种方法详解(转载)

    转载自  http://www.blogjava.net/Todd/archive/2010/04/22/295112.html 方法一:在初始化时保存ApplicationContext对象 代码: ...

  5. applicationcontext获取bean_Spring IoC之ApplicationContext

    概述 在 Spring之IoC理论一章中提到关于 IoC 的学习主要涉及到五大模块,从 Resource 和 ResourceLoader 用于资源管理开始,然后讲述 BeanDefinitionRe ...

  6. java this context,java – Spring XML中applicationcontext的“this”引用

    有没有办法在Spring中的bean配置文件中引用当前的应用程序上下文? 我想做这样的事情: xmlns="http://www.springframework.org/schema/bea ...

  7. applicationContext.xml 的位置问题

    2019独角兽企业重金招聘Python工程师标准>>> 当applicationContext.xml在WEB_INFO下时,得到bean可以这样 ServletContext se ...

  8. 在代码中获取ApplicationContext实例

    基于Spring的Java应用会通过ApplicationContext接口提供应用程序配置.我们常常需要在代码中获取当前的ApplicationContext.如在集成测试时,需要通过Applica ...

  9. applicationcontext添加配置_Spring源码分析2 — spring XML配置文件的解析流程

    1 介绍 创建并初始化spring容器中,关键一步就是读取并解析spring XML配置文件.这个过程比较复杂,本文将详细分析整个流程.先看涉及到的关键类. XmlWebApplicationCont ...

  10. spring整合hibernate(注解、xml)applicationContext.xml配置

    每次ssh框架整合都很麻烦,今天有空余时间总结下(主要总结spring+hibernate): 1.注解方式整合: applicationContext.xml配置文件: <?xml versi ...

最新文章

  1. 文件查找和压缩——Linux基本命令(12)
  2. 关于javascript的介绍
  3. Android Java 8使用Lamda报错:Execution failed for task :app:transformJackWithJackForDebug - Android?...
  4. 让Dreamweaver支持phtml
  5. MySQL 主从复制原理及搭建
  6. 请求发送者与接收者解耦——命令模式
  7. 来自ERP的product属性修改
  8. 你会使用回调函数吗?
  9. Web Service实现分布式服务的基本原理
  10. yolo 视频场景行为数据集
  11. CentOS7 通过wget下载文件到指定目录
  12. C/C++之QT攻略——在QT中容易遇到的那些坑,千万别踩了!
  13. IPLAT62--弹窗
  14. ajax跨域请求jsonp
  15. JAVA创建会话的方法_javaweb学习——会话技术(二)
  16. 【转】 解决IllegalStateException: Can not perform this action after onSaveInstanceState
  17. Linux 创建oracle数据库
  18. [转载]【苹果千层派】轻松玩转酥皮_万金油_新浪博客
  19. 图形化生物软件专题(4):MEGAN
  20. 手把手教你操作Tableau——真实公司数据分析项目实例(完整详细,小白也能学会)

热门文章

  1. MLX90640测温系统的实现
  2. TSN 1. Ethernet AVB/TSN 综述
  3. 归一化、标准化、中心化
  4. 如何在watchOS 7中的Apple Watch上设置和使用睡眠应用程序?
  5. 河南省网络安全高校战队联盟CTF训练营-web文件上传第一期
  6. 5 2019-Identification of Autism Based on SVM-RFE and Stacked Sparse Auto-Encoder
  7. csv文件打开乱码解决
  8. 什么情况需要使用Stripe/PayPal轮询系统
  9. client软件怎么卸载 nac_如何在Mac上安全彻底的卸载软件?
  10. 【路径规划】基于拓展随机树(RRT)算法的路径规划问题(Matlab代码实现)