手写最简单的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值