手写springiocxml方式注入对象
生活随笔
收集整理的這篇文章主要介紹了
手写springiocxml方式注入对象
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
什么是SpringIOC
spring ioc指的是控制反轉,IOC容器負責實例化、定位、配置應用程序中的對象及建立這些對象間的依賴。
交由Spring來管理這些,實現解耦
SpringIOC原理
使用反射機制+XML技術
?
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!-- 把對象初始化之后,存在HashMap里面去 放到內存里面去,JVM內存里面去之后,別人只要調用getBean方法之后,去Spring的容器里面去找到一個對象就行了這種方式也可以,這種方式我待會再講,再講注解的時候我會去實現,所以我是把兩種方式都會實現的,待會我講注解方式的時候會詳細講的,在Spring中id如果重復的情況下是會報錯的,所以有的時候是需要做校驗的,找最后默認的也可以,這個看你自己怎么實現,--><bean id="user" class="com.learn.spring.entity.User"></bean></beans> package com.learn.spring.entity;public class User {private Integer id;private String userName;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}} package com.learn.spring;import java.io.InputStream; import java.util.List;import org.apache.commons.lang.StringUtils; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader;/*** 我們先定義這個類* 我會將兩種方式的實現方式* 我們建完ClassPathXmlApplicationContext這個類* 自定義Spring容器框架* xml方式實現* 你們在寫代碼之前* 不要盲目的去寫* 先通過白話文* 他不知道思路* 你先通過白話文知道整個實現過程* 那這個我們怎么實現呢* * * @author Leon.Sun**/ public class ClassPathXmlApplicationContext {// xml路徑地址/*** xml讀取路徑地址* */private String xmlPath;/*** 定義一個構造函數* 傳入xmlPath* * * @param xmlPath*/public ClassPathXmlApplicationContext(String xmlPath) {this.xmlPath = xmlPath;}/*** 這里要傳入一個bean的id過來* 返回的是一個Object對象* 這個方法也返回Object對象* * * @param beanId* @return* @throws Exception*/public Object getBean(String beanId) throws Exception {// 1. 讀取配置文件/*** 解析XML文件* 如果不解析* 我怎么去讀取這個bean* 是不是這樣的* 這肯定要解析* 解析是第一步* 第一步是把XML文件解析一遍* */List<Element> elements = readerXml();/*** 還有一種場景就是我沒有配置任何bean* 代碼根本就不用往下面再走了* 是不是這樣的* 我們是不是可以直接判斷一下* */if (elements == null) {throw new Exception("該配置文件沒有子元素");}// 2. 使用beanId查找對應的class地址/*** 我把xml全部解析了之后* 第二步干嘛* 使用方法參數bean id查找配置文件中bean節點的id信息是否一致* 假設我這個時候傳入userService* 這樣的一個beanid* 查找到了就要獲取他的class地址* 是不是這樣的* 然后方法里面傳入一個參數過來userService* 我能不能找到userService的一個節點* 是不是找到這個節點* * */String beanClass = findXmlByIDClass(elements, beanId);if (StringUtils.isEmpty(beanClass)) {throw new Exception("未找到對應的class地址");}// 3. 使用反射機制初始化,對象/*** 獲取class信息地址* 使用反射機制初始化* * 找到class信息* 拿到信息之后我使用JAVA的反射機制* 初始化之后返回給調用者* 這里有多少個實現方式* * */Class<?> forName = Class.forName(beanClass);return forName.newInstance();}// 讀取配置文件信息/*** 表示解析這樣的一個XML* 這個傳入的可以沒有* 因為它直接拿全局的* 這個大家一定要慢慢的去想* 這個講的非常細* * 解析XML文件信息* 拿到每個節點的信息* 拿到每個文件信息以后* 傳入一個bean的ID去里面去找* 進行反射去實現出來* 你們可以先把這些節點信息給他封裝起來* 怎么封裝呢* * * @return* @throws DocumentException*/public List<Element> readerXml() throws DocumentException {SAXReader saxReader = new SAXReader();if (StringUtils.isEmpty(xmlPath)) {new Exception("xml路徑為空...");}Document read = saxReader.read(getClassXmlInputStream(xmlPath));// 獲取根節點信息/*** 讀取他的根節點* */Element rootElement = read.getRootElement();// 獲取子節點/*** 獲取根節點下的所有的子節點* 獲取這樣的一個子節點之后* 獲取項目下的所有的子節點* 獲取所有子節點element的對象* 獲取完了之后我們再怎么進行實現呢* 這個時候我可以拿到所有的bean的節點* */List<Element> elements = rootElement.elements();/*** 就是判斷是否為空* */if (elements == null || elements.isEmpty()) {return null;}return elements;}// 使用beanid查找該Class地址/*** 是用beanid去查找有沒有這樣的class地址* 我們是不是要調用根節點* * * * @param elements* @param beanId* @return* @throws Exception*/public String findXmlByIDClass(List<Element> elements, String beanId) throws Exception {for (Element element : elements) {// 讀取節點上是否有value/*** 獲取屬性的信息* 這個id就表示當前的userService* * */String beanIdValue = element.attributeValue("id");/*** 如果xml的id等于空的情況下* 就結束當前循環* 你如果使用Spring的時候* 會校驗的* 這個具體看你們自己* */if (beanIdValue == null) {throw new Exception("使用該beanId為查找到元素");}if (!beanIdValue.equals(beanId)) {/*** 結束本次循環* */continue;}// 獲取Class地址屬性/*** 拿到這樣的一個class地址* 拿到之后* 然后用反射去做一個初始化過程* */String classPath = element.attributeValue("class");/*** 如果等于null的情況下它會怎么樣* */if (!StringUtils.isEmpty(classPath)) {return classPath;}}return null;}// 讀取xml配置文件/*** 獲取當前上下文路徑* * @param xmlPath* @return*/public InputStream getClassXmlInputStream(String xmlPath) {InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(xmlPath);return resourceAsStream;}} package com.learn.spring;import com.learn.spring.entity.User;public class Test002 {public static void main(String[] args) throws Exception {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User user = (User) applicationContext.getBean("user");System.out.println(user);}}?
總結
以上是生活随笔為你收集整理的手写springiocxml方式注入对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dom4kj解析xml
- 下一篇: 手写springioc注解注入对象基本实