广告
返回顶部
首页 > 资讯 > 精选 >Spring ApplicationContext加载过程的示例分析
  • 289
分享到

Spring ApplicationContext加载过程的示例分析

2023-06-14 07:06:34 289人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关spring ApplicationContext加载过程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、找准入口,使用ClassPathXmlApplicationCont

这篇文章给大家分享的是有关spring ApplicationContext加载过程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

1、找准入口,使用ClassPathXmlApplicationContext的构造方法加载配置文件,用于加载classPath下的配置文件

//第一行,执行完成之后就完成了spring配置文件的加载,刷新spring上下文ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(    "classpath:spring-mvc.xml");//获取实例BeanPerson person=context.getBean("person",Person.class);

2、ClassPathXmlApplicationContext构造方法源码如下:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)   throws BeansException {  //设置父级的ApplicationContext,null  super(parent);  //1.设置配置文件的路径, 2. 将路径中的占位符${placeholder}使用系统的变量替换  setConfigLocations(configLocations);  if (refresh) {   refresh();  } }

3、主要方法为setConfigLocation(configLocation),这个方法调用其父类AbstractRefreshableConfigApplicationContext中的方法

//locations : 配置文件路径public void setConfigLocations(String[] locations) {  if (locations != null) {   //断言   Assert.noNullElements(locations, "Config locations must not be null");   //存储配置文件路径的数组,存储去掉占位符后的文件路径数组   this.configLocations = new String[locations.length];   //遍历locations,解析占位符   for (int i = 0; i < locations.length; i++) {     //调用resolvePath解析占位符    this.configLocations[i] = resolvePath(locations[i]).trim();   }  }  else {   this.configLocations = null;  } }

4、进入resovePath的源码,实际上执行的是AbstractPropertyResolver的doResolverPlaceholders方法

private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {  //调用PropertyPlaceholderHelper类中的replacePlaceholders方法  return helper.replacePlaceholders(text, new PropertyPlaceholderHelper.PlaceholderResolver() {   public String resolvePlaceholder(String placeholderName) {    return getPropertyAsRawString(placeholderName);   }  }); }

5、进入PropertyHelper的replacePlaceholder方法,实际上调用PropertyPlaceholderHelper的parseStringValue解析占位符

public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {  Assert.notNull(value, "Argument 'value' must not be null.");  //调用的是parseStringValue方法  return parseStringValue(value, placeholderResolver, new HashSet<String>()); } protected String parseStringValue(   String strVal, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) {  //将strval转换成StringBuilder,便于后续到操作  StringBuilder buf = new StringBuilder(strVal);  //this.placeholderPrefix这个是占位符的前缀 ${,在创建PropertyHelper的时候就已经指定了占位符的placeholderPrefix="${" ,placeholderSuffix="}",valueSeparator=":" //获取前缀在这个配置文件路径中的开始索引   int startIndex = strVal.indexOf(this.placeholderPrefix);   while (startIndex != -1) {   //占位符前缀在路径中的结束索引   int endIndex = findPlaceholderEndIndex(buf, startIndex);      //如果结束索引存在   if (endIndex != -1) {        //此时取出${plcaeholder}中的占位符内容placeholder    String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);        //保存取出来的占位符内容placeholder    String originalPlaceholder = placeholder;        //如果占位符中的内容已经被访问过了,抛出出异常返回,递归结束的条件    if (!visitedPlaceholders.add(originalPlaceholder)) {     throw new IllegalArgumentException(       "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");    }        //递归解析已经取出的占位符中的内容 palceholder    placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);            //这个最重要的一步,将解析占位符内容placeholder的值,比如将java.version转换成1.8.0_60    String propVal = placeholderResolver.resolvePlaceholder(placeholder);        if (propVal == null && this.valueSeparator != null) {     int separatorIndex = placeholder.indexOf(this.valueSeparator);     if (separatorIndex != -1) {      String actualPlaceholder = placeholder.substring(0, separatorIndex);      String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());      propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);      if (propVal == null) {       propVal = defaultValue;      }     }    }    //如果解析出来的占位符不为空,比如${java.version}将被解析成 1.8.0_60    if (propVal != null) {     //此时继续递归解析出1.8.0_60中的占位符     propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);     //将路径中的占位符替换成系统变量的值,比如将${java.version} 替换成 1.8.0_60     buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);     if (logger.isTraceEnabled()) {      logger.trace("Resolved placeholder '" + placeholder + "'");     }     //继续在路径字符串中剩余的子串中查找占位符,如果有占位符,那么还会继续解析占位符     startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());    }    else if (this.ignoreUnresolvablePlaceholders) {     // Proceed with unprocessed value.     startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());    }    else {     throw new IllegalArgumentException("Could not resolve placeholder '" +       placeholder + "'" + " in string value \"" + strVal + "\"");    }    //将已转换成功的占位符从以访问的集合中移除即可    visitedPlaceholders.remove(originalPlaceholder);   }   else {    startIndex = -1;   }  }   return buf.toString(); //将解析完成之后的配置文件返回 }

6、然后是ClassPathXmlApplicationContext中的refresh方法,实际上调用的是父类AbstractApplicationContext的方法

//刷新spring上下文public void refresh() throws BeansException, IllegalStateException {  synchronized (this.startupShutdownMonitor) {   //在刷新之前设置一些参数,比如设置开始时间戳,上下文是否激活的标志,输出刷新上下文的信息,验证一些必要的属性   prepareRefresh();    //需要创建beanFactory,如果已经存在beanFactory,那么关闭,详细其请看 10   ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();    // 准备上下文工厂,详情见12   prepareBeanFactory(beanFactory);    try {    //允许子类向后置处理器添加组件    postProcessBeanFactory(beanFactory);     // 调用BeanFactoryPostProcessor和BeanDefintionReGIStoryPostProcessor这两个后置处理器    invokeBeanFactoryPostProcessors(beanFactory);     // 注册BeanPostProcessor,用来拦截bean的创建,详情见 14    registerBeanPostProcessors(beanFactory);     //初始化消息源    initMessageSource();     // 初始化应用程序事件广播器,用户可以自定义一个事件广播器,如果用户没有定义,那么使用默认的事件广播器SimpleApplicationEventMulticaster    initApplicationEventMulticaster();     // 在其他子类中初始化bean    onRefresh();     // 检测事件监听器    registerListeners();     //完成实例化剩余的单例(non-lazy-init)    finishBeanFactoryInitialization(beanFactory);     // 完成刷新,初始化生命周期处理器......    finishRefresh();   }    catch (BeansException ex) {    // Destroy already created singletons to avoid dangling resources.    destroyBeans();     // Reset 'active' flag.    cancelRefresh(ex);     // Propagate exception to caller.    throw ex;   }  } }

7、进入obtainFreshBeanFactory方法

//AbastractApplicationContext的方法protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {  //实际刷新上下文的方法,这个方法就是实际的刷新上下文方法,其中会调用loadBeanDefinitions(beanFactory);加载配置文件中的内容到BeanDefiniton中  refreshBeanFactory();  ConfigurableListableBeanFactory beanFactory = getBeanFactory();  if (logger.isDebugEnabled()) {   logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);  }  return beanFactory; }   //org.springframework.context.support.AbstractRefreshableApplicationContext中的方法 //AbstractApplicationContext的子类中的方法 @Override protected final void refreshBeanFactory() throws BeansException {  //如果其中有beanfactory,那么销毁  if (hasBeanFactory()) {   destroyBeans();   closeBeanFactory();  }    try {   //重新创建一个beanFactory   DefaultListableBeanFactory beanFactory = createBeanFactory();   //设置序列化id   beanFactory.setSerializationId(getId());      //定制beanFactory,设置相关属性,包括是否允许覆盖名称的不同定义的对象及循环依赖以及   //设置@Autowired和@Qualifier,注解解析器QualifierAnnotationAutowireCandidateResolver   customizeBeanFactory(beanFactory);   //加载BeanDefine 详情见 11   loadBeanDefinitions(beanFactory);   synchronized (this.beanFactoryMonitor) {    this.beanFactory = beanFactory;   }  }  catch (IOException ex) {   throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);  } }

8、进入loadBeanDefinitions(beanFactory)方法

 //这个是org.springframework.context.support.AbstractXmlApplicationContext类中的方法 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {    //创建要给beanDefinitionReader,用于读取BeanDefinition  XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);   //配置XmlBeanDefinitionReader  beanDefinitionReader.setEnvironment(this.getEnvironment());  beanDefinitionReader.setResourceLoader(this);   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));   initBeanDefinitionReader(beanDefinitionReader);  //加载BeanDefiniton,主要的功能从配置文件中读取BeanDefiniton注册到注册表中  loadBeanDefinitions(beanDefinitionReader); }

9、prepareBeanFactory:准备BeanFactory

//准备BeanFactory,设置一些参数,比如后置处理器,protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {  //设置类加载器  beanFactory.setBeanClassLoader(getClassLoader());   //设置表达式解析器,用来解析BeanDefiniton中的带有表达式的值  beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));     beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));   // 配置后置处理器,主要的作用就是在spring实例化bean的前后做一些操作  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));    //忽略自动装配的类,这些类都不能使用@Resource或者@Autowired自动装配获取对象  beanFactory.ignoreDependencyInterface(EnvironmentAware.class);  beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);  beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);  beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);  beanFactory.ignoreDependencyInterface(MessageSourceAware.class);  beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);   //注册可解析的自动装配类  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));   //检查这些类是否被  if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {   beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));  }   // 将下面这些类注册到容器中,使用registerSingleton方法注册,我们可以直接从容器中获取这些类的对象使用  if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {   beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());  }  if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {   beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());  }  if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {   beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());  } }

10、调用BeanFactory的后置处理器,主要的功能就是调用注册在容器中的BeanFactoryPostProcessor和BeanDefinitionRegistoryPostProcessor

//实例化和调用BeanFactory后置处理器,必须在单例实例化之前调用protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {  //调用后置处理器注册委托类的方法调用,getBeanFactoryPostProcessors用于获取注册的全部的BeanFactoryPostProcessor  PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); } //实际的调用方法,PostProcessorRegistrationDelegate中的方法public static void invokeBeanFactoryPostProcessors(   ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {   // Invoke BeanDefinitionRegistryPostProcessors first, if any.  Set<String> processedBeans = new HashSet<String>();    //如果beanFactory是BeanDefinitionRegistry的子类,BeanDefinitionRegistry使用来向注册表中注册Bean的元信息的(BeanDefintion)  if (beanFactory instanceof BeanDefinitionRegistry) {   BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;      //存放BeanFactoryPostProcessor   List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();      //存放BeanDefinitionRegistryPostProcessor   List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =     new LinkedList<BeanDefinitionRegistryPostProcessor>();      //遍历。判断是否是BeanDefinitionRegistryPostProcessor实例   for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {     BeanDefinitionRegistryPostProcessor registryPostProcessor =       (BeanDefinitionRegistryPostProcessor) postProcessor;           //调用BeanDefinitionRegistryPostProcessor     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);     //添加     registryPostProcessors.add(registryPostProcessor);    }    else {     //表示这个是BeanFactoryPostProcessor实例,添加进集合     regularPostProcessors.add(postProcessor);    }   }    //--- 根据类型类型获取beanFactory中注册的BeanDefinitionRegistryPostProcessor的bean的所有名称数组   String[] postProcessorNames =     beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);    // ---- 首先调用的是BeanDefinitionRegistryPostProcessor类型的后置处理器      //存放实现PriorityOrdered这个接口的BeanDefinitionRegistryPostProcessor   List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();      //遍历,如果实现了PriorityOrdered这个接口就保存下来   for (String ppName : postProcessorNames) {    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {     priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));     processedBeans.add(ppName);    }   }      //按照优先级排序   OrderComparator.sort(priorityOrderedPostProcessors);   //添加进入集合   registryPostProcessors.addAll(priorityOrderedPostProcessors);      //首先调用实现PriorityOrdered这个接口的BeanDefinitionRegistryPostProcessor   invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);    // ---- 下面是调用实现Orderd这个接口的BeanDefinitionRegistryPostProcessor   postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);   List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();   for (String ppName : postProcessorNames) {    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {     orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));     processedBeans.add(ppName);    }   }   OrderComparator.sort(orderedPostProcessors);   registryPostProcessors.addAll(orderedPostProcessors);   invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);       // ---- 最终调用剩余全部的BeanDefinitionRegistryPostProcessor      boolean reiterate = true;   while (reiterate) {    reiterate = false;    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);    for (String ppName : postProcessorNames) {     if (!processedBeans.contains(ppName)) {      BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);      registryPostProcessors.add(pp);      processedBeans.add(ppName);      pp.postProcessBeanDefinitionRegistry(registry);      reiterate = true;     }    }   }    // 调用BeanFactoryPostProcessor接口中的方法,因为BeanDefitionRegistory继承了这个接口   invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);   invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);  }   else {   // Invoke factory processors registered with the context instance.   invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);  }   //--- 下面是调用实现BeanFactoryPostProcessor接口的类,和上面的流程一样  String[] postProcessorNames =    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);   // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,  // Ordered, and the rest.  List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();  List<String> orderedPostProcessorNames = new ArrayList<String>();  List<String> nonOrderedPostProcessorNames = new ArrayList<String>();  for (String ppName : postProcessorNames) {   if (processedBeans.contains(ppName)) {    // skip - already processed in first phase above   }   else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));   }   else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {    orderedPostProcessorNames.add(ppName);   }   else {    nonOrderedPostProcessorNames.add(ppName);   }  }   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.  OrderComparator.sort(priorityOrderedPostProcessors);  invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.  List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();  for (String postProcessorName : orderedPostProcessorNames) {   orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));  }  OrderComparator.sort(orderedPostProcessors);  invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);   // Finally, invoke all other BeanFactoryPostProcessors.  List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();  for (String postProcessorName : nonOrderedPostProcessorNames) {   nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));  }  invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); }

11、注册BeanPostProcessor,用来拦截Bean的创建,这个接口可以实现在Bean初始化和初始化之后执行相关的操作

//依然这里依然调用的PostProcessorRegistrationDelegate,其中包含了注册后置处理器和调用后置处理器的方法,相当于一个代理人protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {  PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); } //PostProcessorRegistrationDelegate中的注册BeanPostProcessors的方法//其中beanFactory这个新创建的beanFactory,其中的BeanPostProcessor都没有注册,applicationContext这个是之前创建的,其中的处理器已经注册过了public static void registerBeanPostProcessors(   ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {    //根据类型新加载全部的BeanFactoryProcessor的类,  String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);   //创建BeanPostProcessor检测器  int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;  beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));   // Separate between BeanPostProcessors that implement PriorityOrdered,  // Ordered, and the rest.  List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();  List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();  List<String> orderedPostProcessorNames = new ArrayList<String>();  List<String> nonOrderedPostProcessorNames = new ArrayList<String>();  for (String ppName : postProcessorNames) {   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {    BeanPostProcessor pp = 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);   }  }   // First, register the BeanPostProcessors that implement PriorityOrdered.  OrderComparator.sort(priorityOrderedPostProcessors);  registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);   // Next, register the BeanPostProcessors that implement Ordered.  List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();  for (String ppName : orderedPostProcessorNames) {   BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);   orderedPostProcessors.add(pp);   if (pp instanceof MergedBeanDefinitionPostProcessor) {    internalPostProcessors.add(pp);   }  }  OrderComparator.sort(orderedPostProcessors);  registerBeanPostProcessors(beanFactory, orderedPostProcessors);   // Now, register all regular BeanPostProcessors.  List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();  for (String ppName : nonOrderedPostProcessorNames) {   BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);   nonOrderedPostProcessors.add(pp);   if (pp instanceof MergedBeanDefinitionPostProcessor) {    internalPostProcessors.add(pp);   }  }  registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);   // Finally, re-register all internal BeanPostProcessors.  OrderComparator.sort(internalPostProcessors);  registerBeanPostProcessors(beanFactory, internalPostProcessors);   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }

感谢各位的阅读!关于“Spring ApplicationContext加载过程的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Spring ApplicationContext加载过程的示例分析

本文链接: https://www.lsjlt.com/news/268848.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Spring ApplicationContext加载过程的示例分析
    这篇文章给大家分享的是有关Spring ApplicationContext加载过程的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、找准入口,使用ClassPathXmlApplicationCont...
    99+
    2023-06-14
  • 详解Spring ApplicationContext加载过程
    目录1、找准入口,使用ClassPathXmlApplicationContext的构造方法加载配置文件,用于加载classPath下的配置文件2、ClassPathXmlAppli...
    99+
    2022-11-11
  • Spring Security过滤器链加载执行流程的示例分析
    这篇文章主要介绍Spring Security过滤器链加载执行流程的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Spring Security实现原理Spring Security 采用 IoC ...
    99+
    2023-06-22
  • jvm中类加载过程的示例分析
    这篇文章主要介绍jvm中类加载过程的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!类加载过程:1、加载阶段;2、验证阶段;3、准备阶段,主要是将类变量在方法区进行内存分配并进行初始化;4、解析阶段;5、初始化...
    99+
    2023-06-20
  • Spring源码剖析3:懒加载的单例Bean获取过程分析
    spring ioc 容器的加载流程...
    99+
    2023-06-02
  • spring boot微服务场景下apollo加载过程实例分析
    本篇内容主要讲解“spring boot微服务场景下apollo加载过程实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“spring boot微服务场景下apollo加...
    99+
    2023-06-29
  • java类加载的示例分析
    这篇文章将为大家详细讲解有关java类加载的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、说明当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过以下三个步骤对该类进行初始化。2、...
    99+
    2023-06-15
  • 动态加载css的示例分析
    这篇文章给大家分享的是有关动态加载css的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、方法引用来源和应用此动态加载css方法 loadCss,剥离自Sea.js,并...
    99+
    2022-10-19
  • PHP中类加载的示例分析
    这篇“PHP中类加载的示例分析”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“PHP中类加载的示例分析”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的慢慢理解,接下来就让我们进入主题吧。...
    99+
    2023-06-06
  • java类加载器的示例分析
    这篇文章给大家分享的是有关java类加载器的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Java的优点是什么1. 简单,只需理解基本的概念,就可以编写适合于各种情况的应用程序;2. 面向对象;3. 分布...
    99+
    2023-06-14
  • Spring的示例分析
    这篇文章将为大家详细讲解有关Spring的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。WHY在诞生之初,创建Spring的主要目的是用来替代更加重量级的企业级Java技术,尤其是EJB。相对于E...
    99+
    2023-05-30
    spring
  • Android端分页加载库的示例分析
    这篇文章主要介绍了Android端分页加载库的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言RecyclerView几乎在每个app里面都有被使用,但凡使用了列表...
    99+
    2023-06-14
  • JVM.dll装载过程与源代码的示例分析
    今天就跟大家聊聊有关JVM.dll装载过程与源代码的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。JVM.dll是一个包含可由多个程序同时使用的代码和数据的库。例如,在Win...
    99+
    2023-06-17
  • CommonJS中模块加载的示例分析
    这篇文章主要介绍CommonJS中模块加载的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!叨叨一会CommonJSCommon这个英文单词的意思,相信大家都认识,我记得有一个...
    99+
    2022-10-19
  • Vue中加载顺序的示例分析
    这篇文章将为大家详细讲解有关Vue中加载顺序的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在Vuejs 1.0版本中,如果父子组件进行配合,它们的生命周期执行具...
    99+
    2022-10-19
  • javascript模块加载器的示例分析
    这篇文章将为大家详细讲解有关javascript模块加载器的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。定义var MyModules =&...
    99+
    2022-10-19
  • Java中ClassLoader类加载的示例分析
    这篇文章主要为大家展示了“Java中ClassLoader类加载的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java中ClassLoader类加载的示例分析”这篇文章吧。双亲委派模型...
    99+
    2023-05-30
    java classloader
  • Spring源码剖析3:Spring IOC容器的加载过程
    本文转自五月的仓颉 https://www.cnblogs.com/xrq730本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看https://github.com/h3pl/Java-Tuto...
    99+
    2023-06-02
  • Spring AOP的示例分析
    这篇文章主要为大家展示了“Spring AOP的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Spring AOP的示例分析”这篇文章吧。Spring中对AOP的支持Spring中AOP...
    99+
    2023-05-30
    spring aop
  • Mybatis查询延迟加载的示例分析
    小编给大家分享一下Mybatis查询延迟加载的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Mybatis查询延迟加载详...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作