【spring】-- 手寫一個最簡單的IOC框架

一、什麼是springIOC

IOC就是把每個bean(實體類)與bean(實體了)之間的關係交給第三方容器進行管理。java

若是咱們手寫一個最最簡單的IOC,最終效果是怎樣呢?spring

xml配置:app

<beans>
    <bean id="user1" class="com.itmayiedu.entity.UserEntity">
        <property name="userId" value="0001"></property>
        <property name="userName" value="餘勝軍"></property>
    </bean>
    <bean id="user2" class="com.itmayiedu.entity.UserEntity">
        <property name="userId" value="0002"></property>
        <property name="userName" value="張三"></property>
    </bean>
</beans>

java代碼:dom

//1.讀取springxml配置
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.獲取bean對象
TestService testService = (TestService) classPathXmlApplicationContext.getBean("testService"); System.out.println(testService.test());

二、什麼是springIOC底層實現原理

  1.讀取bean的XML配置文件測試

  2.使用beanId查找bean配置,並獲取配置文件中class地址。this

  3.使用Java反射技術實例化對象spa

  4.獲取屬性配置,使用反射技術進行賦值。code

三、詳細步驟

  1.利用傳入的參數獲取xml文件的流,而且利用dom4j解析成Document對象xml

  2.對於Document對象獲取根元素對象<beans>後對下面的<bean>標籤進行遍歷,判斷是否有符合的id.對象

  3.若是找到對應的id,至關於找到了一個Element元素,開始建立對象,先獲取class屬性,根據屬性值利用反射創建對象.

  4.遍歷<bean>標籤下的property標籤,並對屬性賦值.注意,須要單獨處理int,float類型的屬性.由於在xml配置中這些屬性都是以字符串的形式來配置的,所以須要額外處理.

  5.若是屬性property標籤有ref屬性,說明某個屬性的值是一個對象,那麼根據id(ref屬性的值)去獲取ref對應的對象,再給屬性賦值.

  6.返回創建的對象,若是沒有對應的id,或者<beans>下沒有子標籤都會返回null

3.一、創建實體類

public class User { private String userId; private String userName; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }

3.二、使用反射技術完成java代碼

public class ClassPathXmlApplicationContext { private String pathXml = null; public ClassPathXmlApplicationContext(String pathXml) { this.pathXml = pathXml; } public Object getBean(String beanId) throws Exception { if (StringUtils.isEmpty(beanId)) { throw new Exception("beanId is null"); } SAXReader saxReader = new SAXReader(); Document read = saxReader.read(this.getClass().getClassLoader().getResource(pathXml)); // 獲取到根節點
        Element rootElement = read.getRootElement(); // 根節點下全部的子節點
        List<Element> elements = rootElement.elements(); for (Element element : elements) { // 獲取到節點上的屬性
            String id = element.attributeValue("id"); if (StringUtils.isEmpty(id)) { continue; } if (!id.equals(beanId)) { continue; } // 使用java反射機制初始化對象
            String beanClass = element.attributeValue("class"); Class<?> forName = Class.forName(beanClass); Object newInstance = forName.newInstance(); List<Element> propertyElementList = element.elements(); for (Element el : propertyElementList) { String name = el.attributeValue("name"); String value = el.attributeValue("value"); Field declaredField = forName.getDeclaredField(name); declaredField.setAccessible(true); declaredField.set(newInstance, value); } return newInstance; } return null; } }

 3.三、測試

public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext classPath = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = (User) classPath.getBean("user2"); System.out.println(user.getUserId() + "---" + user.getUserName()); }
相關文章
相關標籤/搜索