手寫最簡單的IOC 容器使實現

新建幾個Service與實現類

pom.xm

 <dependencies>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>jaxen</groupId>
            <artifactId>jaxen</artifactId>
            <version>1.2.0</version>
        </dependency>
    </dependencies>

幾個類


public interface TransferService {

    boolean transfer(String fromAccount, String toAccount, BigDecimal money);
}

public class TransferServcieImpl implements TransferService {

//    private AccountDao accountDao = new AccountDaoImpl();
//    private AccountDao accountDao =BeanFactory.getBean("accountDao",AccountDao.class);

    private AccountDao accountDao ;

    @Override
    public boolean transfer(String fromAccount, String toAccount, BigDecimal money) {
        System.out.println("=====開始轉賬====");

        System.err.println("fromAccount "+fromAccount  +" toAccount "+toAccount+ "  money "+money);
        System.err.println(accountDao.toString());
        return true;
    }

    public AccountDao getAccountDao() {
        return accountDao;
    }

    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
}

public interface AccountDao {
}

public class AccountDaoImpl implements AccountDao {
}

聲明xml

在這裏插入圖片描述

<beans>

    <!--id標識 class 類的全限定類名-->
    <bean id="transferService" class="com.liu.spring.service.impl.TransferServcieImpl">
        <property name="AccountDao" ref="accountDao"/>
    </bean>

    <bean id="accountDao" class="com.liu.spring.dao.impl.AccountDaoImpl">
    </bean>
</beans>

使用工廠解析也初始化Bean

public interface MyApplicationContext {

    Object getBean(String id);

    public <T> T getBean(String id,Class<T> clazz);
    
}




實現

package com.liu.spring.factory.impl;

import com.liu.spring.factory.MyApplicationContext;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description
 * @ClassName MyClassPathXmlApplicationContext
 * @Author 劉楠
 * @date 2020.06.23
 */
public class MyClassPathXmlApplicationContext  implements MyApplicationContext {


    private static  final Map<String,Object> beanMap = new HashMap<>();;

    public MyClassPathXmlApplicationContext(String path){
        InputStream inputStream = MyClassPathXmlApplicationContext.class.getClassLoader().getResourceAsStream(path);
        //dom4j解析
        initBeans(inputStream);


    }

    private void initBeans(InputStream inputStream) {

        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(inputStream);
            //獲取根據元素
            Element rootElement = document.getRootElement();
            //獲取所有bean標籤
            List<Element> beanList = rootElement.selectNodes("//bean");

            for (Element element : beanList) {
                String id = element.attributeValue("id");
                String clazz = element.attributeValue("class");
                //使用反射獲取對象
                Class<?> aClass = Class.forName(clazz);
                Object newInstance = aClass.newInstance();
                beanMap.put(id, newInstance);

            }

            //實例化後,維護對象的依賴關係
            List<Element> propertyList = rootElement.selectNodes("//property");

            //解析property獲取父元素
            for (Element element : propertyList) {
                String name = element.attributeValue("name");
                String ref = element.attributeValue("ref");
                //找到當前需要被處理依賴關係的Bean
                Element parent = element.getParent();
                //調用父元素的反射功能
                String parantId = parent.attributeValue("id");
                Object parantObject = beanMap.get(parantId);
                Method[] methods = parantObject.getClass().getMethods();
                for (Method method : methods) {
                    String methodName = method.getName();
                    //這個方法是要要賦值的方法
                    if (methodName.equalsIgnoreCase("set" + name)) {
                        method.invoke(parantObject, beanMap.get(ref));
                    }
                }
                //重新放入容器
                beanMap.put(parantId, parantObject);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }


   @Override
    public Object getBean(String id) {
        return beanMap.get(id);
    }

    @Override
    public <T> T getBean(String id,Class<T> clazz) {
        return(T) beanMap.get(id);
    }
}

測試

public class Test02 {
    private static    MyApplicationContext context;
   static  {
         context = new MyClassPathXmlApplicationContext("beans.xml");
    }

    public static void main(String[] args) {
        Test02 test02 = new Test02();
        TransferService transferService = context.getBean("transferService",TransferService.class);
        transferService.transfer("a", "b", new BigDecimal("100"));
    }
}

結果
=開始轉賬
fromAccount a toAccount b money 100
com.liu.spring.dao.impl.AccountDaoImpl@75a1cd57

地址:https://gitee.com/null_631_9084/myhomework/tree/master/stage01-spring/spring-classroom

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章