您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Spring實現(xiàn)讀取配置文件的方法”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml")); public class XmlBeanFactory extends DefaultListableBeanFactory { //核心代碼,XmlBeanFactory中使用了自定義的XmlBeanDefinitionReader讀取XML文件 XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory){ //讀取XML配置文件的核心代碼 this.reader.loadBeanDefinitions(resource); } }
加載資源文件可以使用Spring提供的類,如
Resource resource = new ClassPathResource("beanFactory.xml"); //getInputStream是在InputStreamResource中定義的唯一方法,它也是Spring對資源封裝的最上層接口 InputStream inputStream = resource.getInputStream();
public interface InputStreamSource { InputStream getInputStream() throws IOException; } public interface Resource extends InputStreamSource { boolean exists(); boolean isReadable(); boolean isOpen(); URL getURL() throws IOException; URI getURI() throws IOException; File getFile() throws IOException; long contentLength() throws IOException; long lastModified() throws IOException; Resource createRelative(String relativePath) throws IOException; String getFilename(); String getDescription(); }
當(dāng)使用new ClassPathResource
將資源文件封裝為Resource
之后,就可以使用XmlBeanDefinitionReader
來讀取配置文件。
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml")); public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory){ this.reader.loadBeanDefinitions(resource); } public int loadBeanDefinitions(Resource resource){ //EncodedResource主要用于對資源文件的編碼處理的 return loadBeanDefinitions(new EncodedResource(resource)); } public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { //通過Set來記錄已經(jīng)加載的資源,它是放在ThreadLocal中 Set<EncodedResource> currentResources = resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<EncodedResource>(4); //放入ThreadLocal中 this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException(); } try { //獲取文件輸入流,上面已經(jīng)分析過 InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //真正進(jìn)入讀取的邏輯核心部分,此處傳入的inputSource是org.xml.sax.InputResource,用于sax解析 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } } protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource){ try { //步驟1,獲取XML文件的驗證模式,Spring用來校驗驗證模式的方法就是判斷是否包含DOCTYPE,如果包含就是DTD,否則就是XSD int validationMode = getValidationModeForResource(resource); //步驟2,加載XML文件,并得到對應(yīng)的Document Document doc = this.documentLoader.loadDocument( inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware()); //步驟3,根據(jù)返回的Document注冊Bean信息 return registerBeanDefinitions(doc, resource); } } //步驟2 public Document loadDocument(InputSource inputSource, EntityResolver entityResolver, ErrorHandler errorHandler, int validationMode, boolean namespaceAware){ //SAX解析XML文檔,返回Document對象 DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware); DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler); return builder.parse(inputSource); } //步驟3 public int registerBeanDefinitions(Document doc, Resource resource) { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); //設(shè)置環(huán)境變量 documentReader.setEnvironment(this.getEnvironment()); //記錄之前BeanDefinition中定義的Bean的數(shù)量 int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //返回本次加載的BeanDefinition個數(shù) return getRegistry().getBeanDefinitionCount() - countBefore; }
documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext){ this.readerContext = readerContext; //讀取的根元素,debug時顯示為[beans: null] Element root = doc.getDocumentElement(); doRegisterBeanDefinitions(root); } protected void doRegisterBeanDefinitions(Element root) { //處理profile元素,profile標(biāo)簽可以用于配置生產(chǎn)環(huán)境、開發(fā)環(huán)境等 String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { Assert.state(this.environment != null, "Environment must set for evaluating profiles"); String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!this.environment.acceptsProfiles(specifiedProfiles)) { return; } } //專門處理解析的代理 BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(this.readerContext, root, parent); //此處的兩個方法為空實現(xiàn),面向繼承設(shè)計,這是模板方法模式,子類可以繼承并在解析前做一些處理 preProcessXml(root); parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; } 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)) { //解析默認(rèn)標(biāo)簽,如bean parseDefaultElement(ele, delegate); } else { //解析自定義標(biāo)簽,如<aop:aspectj-autoproxy/> delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
“Spring實現(xiàn)讀取配置文件的方法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。