自定义IOC容器(配置文件+反射)

72 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

第一步:准备一个配置文件

  • 在resources目录下创建一个beans.xml文件,这个文件名大家可以自己随便取,我这里就已beans.xml为例。
  • 在当前配置文件中给一个beans根标签<beans></beans>,在这标签里面主要用来配置bean标签,因为我们有可能要生成实例对象存在IOC容器中的对象有很多,所以我们可以配置很多很多的bean标签。那么最外面就是beans根标签,子标签就是bean。
  • bean标签有两个属性
    • id:标识
    • class:存的就是要生成实例的类的全路径(不是接口的路径,是实现类的路径)
<beans>
    <!--  id:标识 class:存的就是要生成实例的类的全路径  -->
    <bean id="userDao" class="com.rg.dao.impl.UserDaoImpl"></bean>
</beans>

第二步:编写一个工厂工具类

  • 创建一个类BeanFactory
  • 使用静态代码块,随着类的加载而加载,只要我们去调用Beanfactory,静态代码块就会去执行,同时静态代码块只会执行一次
  • 在静态代码块中,首先要读取配置文件
  • 使用dom4j解析读取到的配置文件xml
  • 编写xpath表达式
  • 根据xpath表达式获取所有的bean标签
  • 遍历并使用反射创建对象实例,存到map集合(ioc容器)中
  • 在当前类中创建一个静态方法getBean
public class BeanFactory {

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

    // 程序启动时,初始化对象实例
    static {

        // 1.读取配置文件
        InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");

        // 2.解析xml(dom4j)
        SAXReader saxReader = new SAXReader();
        try {
            Document document = saxReader.read(resourceAsStream);
            // 3.编写xpath表达式
            String xpath = "//bean";

            // 4.获取到所有的bean标签
            List<Element> list = document.selectNodes(xpath);
            for (Element element : list) {
                String id = element.attributeValue("id");
                String className = element.attributeValue("class");
                // 使用反射生成实例对象
                Object o = Class.forName(className).newInstance();
                // 存到map中
                iocMap.put(id,o);
            }

        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    public static Object getBean(String beanId) {
        Object o = iocMap.get(beanId);
        return o;
    }

}