anyeeye 发表于 2013-1-29 23:54:29

初探spring applicationContext在web容器中加载过程 首先从WEB.XML入手 ==>web.x

AbstractBeanDefinitionReader.loadBeanDefinitions() 1234567891011121314151617181920212223242526272829303132333435
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {    ResourceLoader resourceLoader = getResourceLoader();    if (resourceLoader == null) {      throw new BeanDefinitionStoreException(          "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");    }   if (resourceLoader instanceof ResourcePatternResolver) {      // Resource pattern matching available.      try {//根据配置文件读取相应配置      Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);      int loadCount = loadBeanDefinitions(resources);      if (logger.isDebugEnabled()) {          logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");      }      return loadCount;      }      catch (IOException ex) {      throw new BeanDefinitionStoreException(            "Could not resolve bean definition resource pattern [" + location + "]", ex);      }    }    else {      // Can only load single resources by absolute URL.      Resource resource = resourceLoader.getResource(location);      int loadCount = loadBeanDefinitions(resource);      if (logger.isDebugEnabled()) {      logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");      }      return loadCount;    }}

这个是其中一个ResourceLoader的实现 ==>PathMatchingResourcePatternResolver.getResources(String locationPattern); 1234567891011121314151617181920212223242526272829
public Resource[] getResources(String locationPattern) throws IOException {    Assert.notNull(locationPattern, "Location pattern must not be null");    if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {      // a class path resource (multiple resources for same name possible)      if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {      // a class path resource pattern      return findPathMatchingResources(locationPattern);      }      else {      // all class path resources with the given name      return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));      }    }    else {      // Only look for a pattern after a prefix here      // (to not get fooled by a pattern symbol in a strange prefix).      int prefixEnd = locationPattern.indexOf(":") + 1;      if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {      // a file pattern      return findPathMatchingResources(locationPattern);      }      else {      // a single resource with the given name      return new Resource[] {getResourceLoader().getResource(locationPattern)};      }    }}

==>PathMatchingResourcePatternResolver.findPathMatchingResources(String locationPattern); 12345678910111213141516171819202122
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {    String rootDirPath = determineRootDir(locationPattern);    String subPattern = locationPattern.substring(rootDirPath.length());    Resource[] rootDirResources = getResources(rootDirPath);//collectionFactory初始化一个set容量为16    Set result = CollectionFactory.createLinkedSetIfPossible(16);    for (int i = 0; i < rootDirResources.length; i++) {      Resource rootDirResource = rootDirResources;      if (isJarResource(rootDirResource)) {      result.addAll(doFindPathMatchingJarResources(rootDirResource, subPattern));      }      else {      result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));      }    }    if (logger.isDebugEnabled()) {      logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result);    }    return (Resource[]) result.toArray(new Resource);}

前面说到有一个刷新WebApplicationContext的操作,但是XmlWebApplicationContext 并没有实现refresh方法,而方法的实现写在 AbstractRefreshableWebApplicationContext 中 ==>AbstractRefreshableWebApplicationContext.refresh(); 1234567
public void refresh() throws BeansException {    if (ObjectUtils.isEmpty(getConfigLocations())) {      //设置configLocations为默认的getDefaultConfigLocations()      setConfigLocations(getDefaultConfigLocations());    }    super.refresh();}

==>AbstractApplicationContext.refresh(); 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
public void refresh() throws BeansException, IllegalStateException {    synchronized (this.startupShutdownMonitor) {      this.startupTime = System.currentTimeMillis();       synchronized (this.activeMonitor) {      this.active = true;      }       // Tell subclass to refresh the internal bean factory.      refreshBeanFactory();      ConfigurableListableBeanFactory beanFactory = getBeanFactory();       // Tell the internal bean factory to use the context's class loader.      beanFactory.setBeanClassLoader(getClassLoader());       // Populate the bean factory with context-specific resource editors.      beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));       // Configure the bean factory with context semantics.      beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));      beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);      beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);      beanFactory.ignoreDependencyInterface(MessageSourceAware.class);      beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);       // Allows post-processing of the bean factory in context subclasses.      postProcessBeanFactory(beanFactory);       // Invoke factory processors registered with the context instance.      for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {      BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();      factoryProcessor.postProcessBeanFactory(beanFactory);      }       if (logger.isInfoEnabled()) {      if (getBeanDefinitionCount() == 0) {          logger.info("No beans defined in application context [" + getDisplayName() + "]");      }      else {          logger.info(getBeanDefinitionCount() + " beans defined in application context [" +getDisplayName() + "]");      }      }       try {      // Invoke factory processors registered as beans in the context.      invokeBeanFactoryPostProcessors();         // Register bean processors that intercept bean creation.      registerBeanPostProcessors();         // Initialize message source for this context.      initMessageSource();         // Initialize event multicaster for this context.      initApplicationEventMulticaster();         // Initialize other special beans in specific context subclasses.      onRefresh();         // Check for listener beans and register them.      registerListeners();         // Instantiate singletons this late to allow them to access the message source.      beanFactory.preInstantiateSingletons();         // Last step: publish corresponding event.      publishEvent(new ContextRefreshedEvent(this));      }       catch (BeansException ex) {      // Destroy already created singletons to avoid dangling resources.      beanFactory.destroySingletons();      throw ex;      }    }}
页: [1]
查看完整版本: 初探spring applicationContext在web容器中加载过程 首先从WEB.XML入手 ==>web.x