您好,登錄后才能下訂單哦!
本篇內容介紹了“Spring實現讀取配置文件的方法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
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(); }
當使用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來記錄已經加載的資源,它是放在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 { //獲取文件輸入流,上面已經分析過 InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //真正進入讀取的邏輯核心部分,此處傳入的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文件,并得到對應的Document Document doc = this.documentLoader.loadDocument( inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware()); //步驟3,根據返回的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(); //設置環境變量 documentReader.setEnvironment(this.getEnvironment()); //記錄之前BeanDefinition中定義的Bean的數量 int countBefore = getRegistry().getBeanDefinitionCount(); documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); //返回本次加載的BeanDefinition個數 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標簽可以用于配置生產環境、開發環境等 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); //此處的兩個方法為空實現,面向繼承設計,這是模板方法模式,子類可以繼承并在解析前做一些處理 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)) { //解析默認標簽,如bean parseDefaultElement(ele, delegate); } else { //解析自定義標簽,如<aop:aspectj-autoproxy/> delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
“Spring實現讀取配置文件的方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。