Spring管理bean(Java中的對象),初始化的操做,java
Resource,對資源文件的描述,不一樣資源文件如xml、properties文件等,格式不一樣,最終都將被ResourceLoader加載得到相應的Resource對象;我的理解是。主配置文件.主配置做爲全部配置的入口spring
ResourceLoader:加載xml、properties等各種格式文件,解析文件,並生成Resource對象。加載哪些解析過的配置資源數據結構
BeanFactory體系:IoC容器的核心,其餘組件都是爲它工做的(但不是僅僅爲其服務).核心框架
SingletonBeanRegister/AliasRegister:將BeanDefinition對象註冊到BeanFactory(BeanDefinition Map)中去。註冊對象所使用的容器dom
BeanDefinition體系,Spring內部對Bean描述的基本數據結構。負責描述BeanDefinition資源 將資源形式的bean轉化爲spring所指望的格式結構ide
BeanDefinitionReader體系,讀取Resource並將其數據轉換成一個個BeanDefinition對象。負責將一個個的資源 解析轉化爲BeanDefinition 爲以後描述bean作準備測試
<img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gg9jtxriloj31330mi0w2.jpg" alt="image-20200205095809050" style="zoom:50%;float:left" />this
bean-v1.xml
配置bean
的信息BeanDefinition
用於存放bean
的定義BeanFactory
獲取bean的信息,實例化
bean`BeanFactoryTest
測試BeanFactory
是否可用bean-v1.xmlcode
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="user" class="com.timwang.spring.small.User"/> <bean id="invalidBean" class="xxx.xxx"/> </beans>
BeanDefinitionxml
bean-v1.xml
中定義了每一個bean
,但這些信息咱們該如何存儲呢? spring
是經過BeanDefinition
接口來描述bean
的定義
package com.timwang.spring.small; /** * @author wangjun
*/
public interface BeanDefinition {
/** * 獲取bean.xml中 bean的全名 如 "com.niocoder.service.v1.NioCoderService" * @return string */ String getBeanClassName();
}
`GenericBeanDefinition`實現了`BeanDefinition`接口
package com.timwang.spring.small;
/**
* @author wangjun * @date 2020-06-29 */
public class GenericBeanDefinition implements BeanDefinition {
private String id; private String beanClassName; public GenericBeanDefinition(String id, String beanClassName) { this.id = id; this.beanClassName = beanClassName; } @Override public String getBeanClassName() { return this.beanClassName; } public String getId() { return id; }
}
3. BeanFactory 咱們已經使用`BeanDefinition`來描述`bean-v1.xml`的`bean`的定義,下面咱們使用`BeanFactory`來獲取`bean`的實例
package com.timwang.spring.small;
/**
* 建立bean的實例 * @author wangjun * @date 2020-06-29 */
public interface BeanFactory {
/** * 獲取bean的定義 * @param beanId beanId * @return BeanDefinition */ BeanDefinition getBeanDefinition(String beanId); /** * 獲取bean的實例 * @param beanId beanId * @return bean示例 */ Object getBean(String beanId);
}
`DefaultBeanFactory`實現了`BeanFactory`接口
package com.timwang.spring.small;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.util.ClassUtils;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.dom4j.io.SAXReader;
/**
* BeanFactory的默認實現類 * * @author wangjun * @date 2020-06-29 */
public class DefaultBeanFactory implements BeanFactory {
private static final String ID_ATTRIBUTE = "id"; private static final String CLASS_ATTRIBUTE = "class"; /** * 存放BeanDefinition */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); public DefaultBeanFactory(String configFile) { loadBeanDefinition(configFile); } @Override public BeanDefinition getBeanDefinition(String beanId) { return beanDefinitionMap.get(beanId); } @Override public Object getBean(String beanId) { BeanDefinition bd = this.getBeanDefinition(beanId); if (bd == null) { throw new BeanCreationException("BeanDefinition does not exist"); } ClassLoader classLoader = ClassUtils.getDefaultClassLoader(); String beanClassName = bd.getBeanClassName(); try { // 使用反射建立bean的實例,須要對象存在默認的無參構造方法 Class<?> aClass = classLoader.loadClass(beanClassName); return aClass.newInstance(); } catch (Exception e) { throw new BeanCreationException("Bean Definition does not exist"); } } /** * 具體解析bean.xml的方法 使用dom4j * @param configFile configFile */ private void loadBeanDefinition(String configFile) { ClassLoader cl = ClassUtils.getDefaultClassLoader(); try (InputStream is = cl.getResourceAsStream(configFile)) { SAXReader reader = new SAXReader(); Document doc = reader.read(is); Element root = doc.getRootElement(); Iterator elementIterator = root.elementIterator(); while (elementIterator.hasNext()) { Element ele = (Element) elementIterator.next(); String id = ele.attributeValue(ID_ATTRIBUTE); String beanClassName = ele.attributeValue(CLASS_ATTRIBUTE); BeanDefinition bd = new GenericBeanDefinition(id, beanClassName); this.beanDefinitionMap.put(id, bd); } } catch (Exception e) { throw new BeanDefinitionStoreException("IOException parsing XML document", e); } }
}
4. BeanFactoryTest
package com.timwang.spring.small;
/**
* @author wangjun * @date 2020-06-29 */
public class BeanFactoryTest {
public static void main(String[] args) { BeanFactoryTest beanFactoryTest = new BeanFactoryTest(); beanFactoryTest.testGetBean(); } public void testGetBean() { BeanFactory beanFactory = new DefaultBeanFactory("bean-v1.xml"); BeanDefinition bd = beanFactory.getBeanDefinition("user"); String beanClassName = bd.getBeanClassName(); System.out.println(beanClassName); }
}