春天里

public abstract class AbstractApplicationContext extends DefaultResourceLoader  implements ConfigurableApplicationContext, DisposableBean

 1     @Override
 2     public void refresh() throws BeansException, IllegalStateException {
 3         synchronized (this.startupShutdownMonitor) {
 4             // Prepare this context for refreshing.
 5             prepareRefresh();
 6 
 7             // Tell the subclass to refresh the internal bean factory.
 8             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 9 
10             // Prepare the bean factory for use in this context.
11             prepareBeanFactory(beanFactory);
12 
13             try {
14                 // Allows post-processing of the bean factory in context subclasses.
15                 postProcessBeanFactory(beanFactory);
16 
17                 // Invoke factory processors registered as beans in the context.
18                 invokeBeanFactoryPostProcessors(beanFactory);
19 
20                 // Register bean processors that intercept bean creation.
21                 registerBeanPostProcessors(beanFactory);
22 
23                 // Initialize message source for this context.
24                 initMessageSource();
25 
26                 // Initialize event multicaster for this context.
27                 initApplicationEventMulticaster();
28 
29                 // Initialize other special beans in specific context subclasses.
30                 onRefresh();
31 
32                 // Check for listener beans and register them.
33                 registerListeners();
34 
35                 // Instantiate all remaining (non-lazy-init) singletons.
36                 finishBeanFactoryInitialization(beanFactory);
37 
38                 // Last step: publish corresponding event.
39                 finishRefresh();
40             }
41 
42             catch (BeansException ex) {
43                 // Destroy already created singletons to avoid dangling resources.
44                 destroyBeans();
45 
46                 // Reset 'active' flag.
47                 cancelRefresh(ex);
48 
49                 // Propagate exception to caller.
50                 throw ex;
51             }
52         }
53     }
 1     /**
 2      * Tell the subclass to refresh the internal bean factory.
 3      * @return the fresh BeanFactory instance
 4      * @see #refreshBeanFactory()
 5      * @see #getBeanFactory()
 6      */
 7     protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
 8         refreshBeanFactory();
 9         ConfigurableListableBeanFactory beanFactory = getBeanFactory();
10         if (logger.isDebugEnabled()) {
11             logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
12         }
13         return beanFactory;
14     }
 1 public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
 2 
 3 
 4     /**
 5      * This implementation performs an actual refresh of this context's underlying
 6      * bean factory, shutting down the previous bean factory (if any) and
 7      * initializing a fresh bean factory for the next phase of the context's lifecycle.
 8      */
 9     @Override
10     protected final void refreshBeanFactory() throws BeansException {
11         if (hasBeanFactory()) {
12             destroyBeans();
13             closeBeanFactory();
14         }
15         try {
16             DefaultListableBeanFactory beanFactory = createBeanFactory();
17             beanFactory.setSerializationId(getId());
18             customizeBeanFactory(beanFactory);
19             loadBeanDefinitions(beanFactory);
20             synchronized (this.beanFactoryMonitor) {
21                 this.beanFactory = beanFactory;
22             }
23         }
24         catch (IOException ex) {
25             throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
26         }
27     }
28 }
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
    /**
     * Loads the bean definitions via an XmlBeanDefinitionReader.
     * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
     * @see #initBeanDefinitionReader
     * @see #loadBeanDefinitions
     */
    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // Create a new XmlBeanDefinitionReader for the given BeanFactory.
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // Configure the bean definition reader with this context's
        // resource loading environment.
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // Allow a subclass to provide custom initialization of the reader,
        // then proceed with actually loading the bean definitions.
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }
    /**
     * Load the bean definitions with the given XmlBeanDefinitionReader.
     * <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory}
     * method; hence this method is just supposed to load and/or register bean definitions.
     * @param reader the XmlBeanDefinitionReader to use
     * @throws BeansException in case of bean registration errors
     * @throws IOException if the required XML document isn't found
     * @see #refreshBeanFactory
     * @see #getConfigLocations
     * @see #getResources
     * @see #getResourcePatternResolver
     */
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        Resource[] configResources = getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        String[] configLocations = getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }
}

 

 1 public abstract class AbstractBeanDefinitionReader implements EnvironmentCapable, BeanDefinitionReader {
 2     @Override
 3     public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
 4         Assert.notNull(locations, "Location array must not be null");
 5         int counter = 0;
 6         for (String location : locations) {
 7             counter += loadBeanDefinitions(location);
 8         }
 9         return counter;
10     }
11 
12     @Override
13     public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
14         return loadBeanDefinitions(location, null);
15     }
16 
17     /**
18      * Load bean definitions from the specified resource location.
19      * <p>The location can also be a location pattern, provided that the
20      * ResourceLoader of this bean definition reader is a ResourcePatternResolver.
21      * @param location the resource location, to be loaded with the ResourceLoader
22      * (or ResourcePatternResolver) of this bean definition reader
23      * @param actualResources a Set to be filled with the actual Resource objects
24      * that have been resolved during the loading process. May be {@code null}
25      * to indicate that the caller is not interested in those Resource objects.
26      * @return the number of bean definitions found
27      * @throws BeanDefinitionStoreException in case of loading or parsing errors
28      * @see #getResourceLoader()
29      * @see #loadBeanDefinitions(org.springframework.core.io.Resource)
30      * @see #loadBeanDefinitions(org.springframework.core.io.Resource[])
31      */
32     public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
33         ResourceLoader resourceLoader = getResourceLoader();
34         if (resourceLoader == null) {
35             throw new BeanDefinitionStoreException(
36                     "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
37         }
38 
39         if (resourceLoader instanceof ResourcePatternResolver) {
40             // Resource pattern matching available.
41             try {
42                 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
43                 int loadCount = loadBeanDefinitions(resources);
44                 if (actualResources != null) {
45                     for (Resource resource : resources) {
46                         actualResources.add(resource);
47                     }
48                 }
49                 if (logger.isDebugEnabled()) {
50                     logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
51                 }
52                 return loadCount;
53             }
54             catch (IOException ex) {
55                 throw new BeanDefinitionStoreException(
56                         "Could not resolve bean definition resource pattern [" + location + "]", ex);
57             }
58         }
59         else {
60             // Can only load single resources by absolute URL.
61             Resource resource = resourceLoader.getResource(location);
62             int loadCount = loadBeanDefinitions(resource);
63             if (actualResources != null) {
64                 actualResources.add(resource);
65             }
66             if (logger.isDebugEnabled()) {
67                 logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
68             }
69             return loadCount;
70         }
71     }
72     @Override
73     public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
74         Assert.notNull(resources, "Resource array must not be null");
75         int counter = 0;
76         for (Resource resource : resources) {
77             counter += loadBeanDefinitions(resource);
78         }
79         return counter;
80     }
81 }

 

public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {

    /**
     * Load bean definitions from the specified XML file.
     * @param resource the resource descriptor for the XML file
     * @return the number of bean definitions found
     * @throws BeanDefinitionStoreException in case of loading or parsing errors
     */
    @Override
    public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        return loadBeanDefinitions(new EncodedResource(resource));
    }


    /**
     * Load bean definitions from the specified XML file.
     * @param encodedResource the resource descriptor for the XML file,
     * allowing to specify an encoding to use for parsing the file
     * @return the number of bean definitions found
     * @throws BeanDefinitionStoreException in case of loading or parsing errors
     */
    public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        Assert.notNull(encodedResource, "EncodedResource must not be null");
        if (logger.isInfoEnabled()) {
            logger.info("Loading XML bean definitions from " + encodedResource.getResource());
        }

        Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
        if (currentResources == null) {
            currentResources = new HashSet<EncodedResource>(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }
        if (!currentResources.add(encodedResource)) {
            throw new BeanDefinitionStoreException(
                    "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        }
        try {
            InputStream inputStream = encodedResource.getResource().getInputStream();
            try {
                InputSource inputSource = new InputSource(inputStream);
                if (encodedResource.getEncoding() != null) {
                    inputSource.setEncoding(encodedResource.getEncoding());
                }
                return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
            }
            finally {
                inputStream.close();
            }
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(
                    "IOException parsing XML document from " + encodedResource.getResource(), ex);
        }
        finally {
            currentResources.remove(encodedResource);
            if (currentResources.isEmpty()) {
                this.resourcesCurrentlyBeingLoaded.remove();
            }
        }
    }


    /**
     * Actually load bean definitions from the specified XML file.
     * @param inputSource the SAX InputSource to read from
     * @param resource the resource descriptor for the XML file
     * @return the number of bean definitions found
     * @throws BeanDefinitionStoreException in case of loading or parsing errors
     * @see #doLoadDocument
     * @see #registerBeanDefinitions
     */
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
            throws BeanDefinitionStoreException {
        try {
            Document doc = doLoadDocument(inputSource, resource);
            return registerBeanDefinitions(doc, resource);
        }
        catch (BeanDefinitionStoreException ex) {
            throw ex;
        }
        catch (SAXParseException ex) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(),
                    "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
        }
        catch (SAXException ex) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(),
                    "XML document from " + resource + " is invalid", ex);
        }
        catch (ParserConfigurationException ex) {
            throw new BeanDefinitionStoreException(resource.getDescription(),
                    "Parser configuration exception parsing XML from " + resource, ex);
        }
        catch (IOException ex) {
            throw new BeanDefinitionStoreException(resource.getDescription(),
                    "IOException parsing XML document from " + resource, ex);
        }
        catch (Throwable ex) {
            throw new BeanDefinitionStoreException(resource.getDescription(),
                    "Unexpected exception parsing XML document from " + resource, ex);
        }
    }


    /**
     * Register the bean definitions contained in the given DOM document.
     * Called by {@code loadBeanDefinitions}.
     * <p>Creates a new instance of the parser class and invokes
     * {@code registerBeanDefinitions} on it.
     * @param doc the DOM document
     * @param resource the resource descriptor (for context information)
     * @return the number of bean definitions found
     * @throws BeanDefinitionStoreException in case of parsing errors
     * @see #loadBeanDefinitions
     * @see #setDocumentReaderClass
     * @see BeanDefinitionDocumentReader#registerBeanDefinitions
     */
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        documentReader.setEnvironment(this.getEnvironment());
        int countBefore = getRegistry().getBeanDefinitionCount();
        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
        return getRegistry().getBeanDefinitionCount() - countBefore;
    }
}

 

public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {

    /**
     * {@inheritDoc}
     * <p>This implementation parses bean definitions according to the "spring-beans" XSD
     * (or DTD, historically).
     * <p>Opens a DOM Document; then initializes the default settings
     * specified at the {@code <beans/>} level; then parses the contained bean definitions.
     */
    @Override
    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        logger.debug("Loading bean definitions");
        Element root = doc.getDocumentElement();
        doRegisterBeanDefinitions(root);
    }
    /**
     * Register each bean definition within the given root {@code <beans/>} element.
     * @throws IllegalStateException if {@code <beans profile="..."} attribute is present
     * and Environment property has not been set
     * @see #setEnvironment
     */
    protected void doRegisterBeanDefinitions(Element root) {
        String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
        if (StringUtils.hasText(profileSpec)) {
            Assert.state(this.environment != null, "Environment must be set for evaluating profiles");
            String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                    profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            if (!this.environment.acceptsProfiles(specifiedProfiles)) {
                return;
            }
        }

        // Any nested <beans> elements will cause recursion in this method. In
        // order to propagate and preserve <beans> default-* attributes correctly,
        // keep track of the current (parent) delegate, which may be null. Create
        // the new (child) delegate with a reference to the parent for fallback purposes,
        // then ultimately reset this.delegate back to its original (parent) reference.
        // this behavior emulates a stack of delegates without actually necessitating one.
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = createDelegate(this.readerContext, root, parent);

        preProcessXml(root);
        parseBeanDefinitions(root, this.delegate);
        postProcessXml(root);

        this.delegate = parent;
    }


    /**
     * Parse the elements at the root level in the document:
     * "import", "alias", "bean".
     * @param root the DOM root element of the document
     */
    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
            NodeList nl = root.getChildNodes();
            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)) {
                        parseDefaultElement(ele, delegate);
                    }
                    else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        }
        else {
            delegate.parseCustomElement(root);
        }
    }
    private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            importBeanDefinitionResource(ele);
        }
        else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            processAliasRegistration(ele);
        }
        else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            processBeanDefinition(ele, delegate);
        }
        else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
            // recurse
            doRegisterBeanDefinitions(ele);
        }
    }

}

 

public class BeanDefinitionParserDelegate {

      public BeanDefinition parseCustomElement(Element ele) {
        return parseCustomElement(ele, null);
    }

    public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
        String namespaceUri = getNamespaceURI(ele);
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
        if (handler == null) {
            error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
            return null;
        }
        return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    }
  

}

 

转载于:https://www.cnblogs.com/shapeOfMyHeart/p/5016777.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值