首页 > 代码库 > spring容器启动的加载过程(二)
spring容器启动的加载过程(二)
第六步:
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory();//具体实现调用子类容器的refreshBeanFactory()方法 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }...protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException; }
第七步:
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {/** Bean factory for this context */ private DefaultListableBeanFactory beanFactory; protected final void refreshBeanFactory() throws BeansException { //如果已经有beanfactory了,则销毁所有的bean,关闭beanfactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { //得到一个默认的DefaultListableBeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //对IoC容器进行定制化,如设置启动参数,开启注解的自动装配等 customizeBeanFactory(beanFactory); //调用载入Bean定义的方法,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } //创建beanfactory protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); } ...
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException; }
第八步:
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { /** Default config location for the root context */ public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; /** Default prefix for building a config location for a namespace */ public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; /** Default suffix for building a config location for a namespace */ public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; @Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. //创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容器使用该读取器读取Bean定义资源 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context‘s // resource loading environment. //设置环境 beanDefinitionReader.setEnvironment(this.getEnvironment()); //为Bean读取器设置Spring资源加载器,AbstractXmlApplicationContext的祖先父类AbstractApplicationContext,他继承DefaultResourceLoader,因此容器本身也是一个资源加载器 beanDefinitionReader.setResourceLoader(this); //为Bean读取器设置SAX xml解析器 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. //当Bean读取器读取Bean定义的Xml资源文件时,启用Xml的校验机制 initBeanDefinitionReader(beanDefinitionReader); //Bean读取器真正实现加载的方法 loadBeanDefinitions(beanDefinitionReader); } ... protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException { //获取配置资源的定位 String[] configLocations = getConfigLocations(); if (configLocations != null) { for (String configLocation : configLocations) { //XmlBean读取器调用其父类AbstractBeanDefinitionReader读取定位的Bean定义资源 reader.loadBeanDefinitions(configLocation); } } } }
第九步:
public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable, BeanDefinitionReader {//从指定的资源加载bean定义,返回bean定义的数量public int loadBeanDefinitions(String location, Set<Resource> actualResources) 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);//得到加载bean定义的数量,而且在这里将bean定义注入进了spring容器中 if (actualResources != null) { for (Resource resource : resources) { actualResources.add(resource); } } 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 (actualResources != null) { actualResources.add(resource); } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } } public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int counter = 0; for (Resource resource : resources) { counter += loadBeanDefinitions(resource);//加载不同的资源类型,使用不同的具体子类来加载,这里使用的是xml。所以他的子类是XmlBeanDefinitionReader,还有一个子类是PropertiesBeanDefinitionReader } return counter; } }
spring容器启动的加载过程(二)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。