标签:
refresh这个方法包含了整个BeanFactory初始化的过程,定位资源由obtainFreshBeanFactory()来完成,
- protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {  
 
-         refreshBeanFactory();  
 
-         ConfigurableListableBeanFactory beanFactory = getBeanFactory();  
 
-         if (logger.isDebugEnabled()) {  
 
-             logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);  
 
-         }  
 
-         return beanFactory;  
 
-     }  
 
 
         可以看到其调用了refreshBeanFactory(),refreshBeanFactory()在这个类中是抽象方法,其实现在AbstractRefreshableApplicationContext中。
- protected final void refreshBeanFactory() throws BeansException {  
 
-         if (hasBeanFactory()) {  
 
-             destroyBeans();  
 
-             closeBeanFactory();  
 
-         }  
 
-         try {  
 
-             DefaultListableBeanFactory beanFactory = createBeanFactory();  
 
-             beanFactory.setSerializationId(getId());  
 
-             customizeBeanFactory(beanFactory);  
 
-             loadBeanDefinitions(beanFactory);  
 
-             synchronized (this.beanFactoryMonitor) {  
 
-                 this.beanFactory = beanFactory;  
 
-             }  
 
-         }  
 
-         catch (IOException ex) {  
 
-             ……  
 
-         }  
 
- }  
 
 
          在这个方法中,先判断BeanFactory是否存在,如果存在则先销毁beans并关闭beanFactory,接着创建DefaultListableBeanFactory,并调用loadBeanDefinitions(beanFactory)装载bean定义。loadBeanDefinitions方法同样是抽象方法,是由其子类实现的,也即在AbstractXmlApplicationContext中。
- protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {    
 
-    <span style="color:#33ff33;"> 
 
-     XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);    
 
-     
 
-     <span style="color:#33ff33;">
 
-  <span style="color:#33ff33;">   
 
-     beanDefinitionReader.setResourceLoader(this);    
 
-     beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));    
 
-     
 
-     initBeanDefinitionReader(beanDefinitionReader);    
 
-     <span style="color:#33ff33;">
 
-     loadBeanDefinitions(beanDefinitionReader);    
 
- }    
 
 
          接着我们转到beanDefinitionReader中进行处理
- protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {    
 
-     Resource[] configResources = getConfigResources();    
 
-     if (configResources != null) {    
 
-       <span style="color:#33ff33;">  
 
-         reader.loadBeanDefinitions(configResources);    
 
-     }    
 
-     String[] configLocations = getConfigLocations();    
 
-     if (configLocations != null) {    
 
-         reader.loadBeanDefinitions(configLocations);    
 
-     }    
 
- }    
 
 
         可以到org.springframework.beans.factory.support看一下BeanDefinitionReader的结构

        在其抽象父类AbstractBeanDefinitionReader中定义了载入过程
 
- public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {    
 
-    <span style="color:#33ff33;"> 
 
-     ResourceLoader resourceLoader = getResourceLoader();    
 
-     <span style="color:#33ff33;">
 
-     if (resourceLoader instanceof ResourcePatternResolver) {    
 
-         <span style="color:#33ff33;">
 
-         try {    
 
-             Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);    
 
-             int loadCount = loadBeanDefinitions(resources);    
 
-             return loadCount;    
 
-         }    
 
-         ........    
 
-     }    
 
-     else {    
 
-         <span style="color:#33ff33;">
 
-         Resource resource = resourceLoader.getResource(location);    
 
-             <span style="color:#33ff33;"> 
 
-         int loadCount = loadBeanDefinitions(resource);    
 
-         return loadCount;    
 
-     }    
 
- }   
 
 

 
 

        看到第8、16行,结合上面的ResourceLoader与ApplicationContext的继承关系图,可以知道此时调用的是DefaultResourceLoader中的getSource()方法定位Resource,因为ClassPathXmlApplicationContext本身就是DefaultResourceLoader的实现类,所以此时又回到了ClassPathXmlApplicationContext中来。
 
        继续回到XmlBeanDefinitionReader的loadBeanDefinitions(Resource …)方法看得到代表bean文件的资源定义以后的载入过程。
- public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {    
 
-     .......    
 
-     try {    
 
-         <span style="color:#33ff33;">
 
-         InputStream inputStream = encodedResource.getResource().getInputStream();    
 
-         try {    
 
-            <span style="color:#33ff33;"> 
 
-             InputSource inputSource = new InputSource(inputStream);    
 
-             if (encodedResource.getEncoding() != null) {    
 
-                 inputSource.setEncoding(encodedResource.getEncoding());    
 
-             }    
 
-             <span style="color:#33ff33;">
 
-             return doLoadBeanDefinitions(inputSource, encodedResource.getResource());    
 
-         }    
 
-         finally {    
 
-             <span style="BACKGROUND-COLOR: #33ff33">
 
-             inputStream.close();    
 
-         }    
 
-     }    
 
-        .........    
 
- }    
 
-     
 
- protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)    
 
-         throws BeanDefinitionStoreException {    
 
-     try {    
 
-         int validationMode = getValidationModeForResource(resource);    
 
-         <span style="color:#33ff33;">
 
-         Document doc = this.documentLoader.loadDocument(    
 
-                 inputSource, this.entityResolver, this.errorHandler, validationMode, this.namespaceAware);    
 
-         return registerBeanDefinitions(doc, resource);    
 
-     }    
 
- .......    
 
- }  
 
 
        在doLoadBeanDefinitions(…)先把定义文件解析为DOM对象,然后进行具体的注册过程。
- public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {  
 
-         <span style="color:#33ff33;">
 
-         BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();  
 
-         documentReader.setEnvironment(this.getEnvironment());  
 
-         int countBefore = getRegistry().getBeanDefinitionCount();  
 
-         <span style="color:#33ff33;">
 
-                      documentReader.registerBeanDefinitions(doc,createReaderContext(resource));  
 
-              return getRegistry().getBeanDefinitionCount() - countBefore;  
 
- }  
 
- <p> </p>  
 
 
 
        具体的过程在BeanDefinitionDocumentReader中完成,在DefaultBeanDefinitionDocumentReader的方法中完成bean定义文件的解析和IOC容器中bean的初始化。
- public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {  
 
-         this.readerContext = readerContext;  
 
-   
 
-         logger.debug("Loading bean definitions");  
 
-         Element root = doc.getDocumentElement();  
 
-   
 
-         doRegisterBeanDefinitions(root);  
 
- }  
 
 
 
- protected void doRegisterBeanDefinitions(Element root) {  
 
-         <span style="color:#33ff33;">……(注:省略号表示省略掉了代码)  
 
-         
 
-         BeanDefinitionParserDelegate parent = this.delegate;  
 
-         this.delegate = createHelper(readerContext, root, parent);  
 
-   
 
-         preProcessXml(root);  
 
-         parseBeanDefinitions(root, this.delegate);  
 
-         postProcessXml(root);  
 
-   
 
-         this.delegate = parent;  
 
- }  
 
 
 
- protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {  
 
-         if (delegate.isDefaultNamespace(root)) {  
 
-             <span style="color:#33ff33;">
 
-             NodeList nl = root.getChildNodes();  
 
-             <span style="color:#33ff33;">
 
-             for (int i = 0; i < nl.getLength(); i++) {  
 
-                 Node node = nl.item(i);  
 
-                 if (node instanceof Element) {  
 
-                     Element ele = (Element) node;  
 
-                     if (delegate.isDefaultNamespace(ele)) {  
 
-                         <span style="color:#33ff33;">
 
-                         parseDefaultElement(ele, delegate);  
 
-                     }  
 
-                     else {  
 
-                         delegate.parseCustomElement(ele);  
 
-                     }  
 
-                 }  
 
-             }  
 
-         }  
 
-         else {  
 
-             delegate.parseCustomElement(root);  
 
-         }  
 
- }  
 
 
 
- private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {  
 
-         <span style="color:#33ff33;">
 
-         if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {  
 
-             importBeanDefinitionResource(ele);  
 
-         }  
 
-         else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {  
 
-             processAliasRegistration(ele);  
 
-         }  
 
-         <span style="color:#33ff33;">
 
-         else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {  
 
-             processBeanDefinition(ele, delegate);  
 
-         }  
 
-         else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {  
 
-             <span style="color:#33ff33;">
 
-             doRegisterBeanDefinitions(ele);  
 
-         }  
 
- }  
 
 
- protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {  
 
-         <span style="color:#33ff33;">
 
-         BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);  
 
-         if (bdHolder != null) {  
 
-              bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);  
 
-             try {  
 
-                 <span style="color:#33ff33;">
 
-                                
 
 
-                                   BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());  
 
-     }  
 
-     catch (BeanDefinitionStoreException ex) {  
 
-         ……  
 
-     }  
 
-     <span style="color:#33ff33;">
 
-     
 
-                     getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));  
 
- }  
 
 
         可以看到在processBeanDefinition中对具体bean元素的解析是交给BeanDefinitionParserDelegate来完成的。我们接着看其实现的函数:
- public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {  
 
-         <span style="color:#33ff33;">……(省略)</span>  
 
-         AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);  
 
-         if (beanDefinition != null) {  
 
-             <span style="color:#33ff33;">
 
-                                 ……(省略)  
 
-             String[] aliasesArray = StringUtils.toStringArray(aliases);  
 
-                            <span style="color:#33ff33;">
 
-             return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);  
 
-         }  
 
-         return null;  
 
- }  
 
- <p> </p>  
 
 
         在这里对定义文件中的bean元素进行解析,得到AbstractBeanDefinition,并用BeanDefinitionHolder封装后返回。
        下面我们看解析完的bean如何在IOC容器中注册:在BeanDefinitionReaderUtils中调用的是:
- public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)  
 
- throws BeanDefinitionStoreException {  
 
-         <span style="color:#33ff33;">
 
-         
 
-         String beanName = definitionHolder.getBeanName();  
 
-         <span style="color:#33ff33;">
 
-         registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());  
 
-   
 
-         <span style="color:#33ff33;">
 
-         
 
-         String[] aliases = definitionHolder.getAliases();  
 
-         if (aliases != null) {  
 
-             for (String aliase : aliases) {  
 
-                 registry.registerAlias(beanName, aliase);  
 
-             }  
 
-         }  
 
- }  
 
 
         接着我们看看bean的注册实现,从上面看到其调用的是BeanDefinitionRegistry的方法registerBeanDefinition完成注册,跟踪代码可知BeanFactory容器的一个实现DefaultListableBeanFactory实现了这个接口并提供了注册的具体实现:

 
- public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {  
 
-   
 
-         ......  
 
-         if (beanDefinition instanceof AbstractBeanDefinition) {  
 
-             try {  
 
-                 ((AbstractBeanDefinition) beanDefinition).validate();  
 
-             }  
 
-             catch (BeanDefinitionValidationException ex) {  
 
-                 <span style="color:#33ff33;">
 
-                 ……  
 
-             }  
 
-         }  
 
-   
 
-         synchronized (this.beanDefinitionMap) {  
 
-             Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);  
 
-             if (oldBeanDefinition != null) {  
 
-                 if (!this.allowBeanDefinitionOverriding) {  
 
-                     <span style="color:#33ff33;">
 
-                     ……  
 
-                 }  
 
-                 else {  
 
-                     if (this.logger.isInfoEnabled()) {  
 
-                         ……  
 
-                     }  
 
-                 }  
 
-             }  
 
-             else {  
 
-                 this.beanDefinitionNames.add(beanName);  
 
-                 this.frozenBeanDefinitionNames = null;  
 
-             }  
 
-             this.beanDefinitionMap.put(beanName, beanDefinition);  
 
-   
 
-             resetBeanDefinition(beanName);  
 
-         }  
 
- }  
 
 
         可以看到整个注册过程很简单,就是将bean添加到BeanDefinition的map中。这样就完成了bean定义在IOC容器中的注册,就可被IOC容器进行管理和使用了。
spring IOC源码分析(2)
标签:
原文地址:http://www.cnblogs.com/downey/p/4888329.html