> 文章列表 > 手写IOC容器通过xml文件,或者注解

手写IOC容器通过xml文件,或者注解

手写IOC容器通过xml文件,或者注解

68.手写一个IOC容器

  1. 创建容器

  2. xml处理阶段或者注解

  3. 创建对象(反射技术)

  4. 把对象放入容器

  5. 暴露接口给外部使用

    68.1使用xml文件方式?

    调用的client

    package com.hou;/*** @author SmallMonkey* @Date 2023/4/10 11:38**/
    public class Client {public static void main(String[] args) {//这样创建的code的耦合度太高MonkeyObject monkeyObject = new MonkeyObject();monkeyObject.say();//use this method,your code just change the id,you will earn other's objectMonkeyObject monkeyObject1 = (MonkeyObject)IOC.getBean("MonkeyObject");monkeyObject1.say();}
    }

    IOC容器

    package com.hou;import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;import java.io.InputStream;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;/*** @author SmallMonkey* @Date 2023/4/10 11:42**/
    public class IOC {
    //  1. 创建ioc容器: 使用k-v结构方便我们 通过方法进行获取对象static final   Map<String,Object> beanMap = new HashMap<>();static{// 2. xml处理解析//把xml文件从硬盘加载到内存里面 返回二进制文件流InputStream xmlresourceStream = IOC.class.getClassLoader().getResourceAsStream("bean.xml");// 把二进制流文件转换成文本格式SAXReader saxReader = new SAXReader();try {// read xml file return a documentDocument document = saxReader.read(xmlresourceStream);//earn all the text file's root element: for search the root's bean tagsElement rootElement = document.getRootElement();List<Element> list = rootElement.selectNodes("//bean");// pull the bean one by one,from bean earn the id and class tagfor (int i = 0; i < list.size(); i++) {// take the beanElement element = list.get(i);// take the idString id = element.attributeValue("id");// take the classString aclass = element.attributeValue("class");
    //   3. use reflection to create ObjectClass<?> aClass = Class.forName(aclass); // earn .classObject bean = aClass.newInstance();// create object
    //   4. put the object into  map containerbeanMap.put(id,bean);}} catch (Exception e) {e.printStackTrace();}}//    5. expose interface for the External callpublic static Object getBean(String id){return beanMap.get(id);}
    }

    对象:

    package com.hou;/*** @author SmallMonkey* @Date 2023/4/10 11:36**/
    public class MonkeyObject {public static void say(){System.out.println("我的快乐已经还是钱可以solve的。。。。。。");}
    }

    bean.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <beans><bean id="MonkeyObject" class = "com.hou.MonkeyObject"></bean></beans>

    引入的依赖:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.monkey</groupId><artifactId>SimpleIOC</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies>
    <!--        it's convinient to parse the xml document--><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><!--it's convinient to search the element--><dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.1.6</version></dependency></dependencies></project>

    68.3 使用注解的形式

    自定义IOC容器的步骤如下:

    1. 定义注解:定义一个注解,用于标注需要被IOC容器管理的类。例如,可以定义一个@MyComponent注解。
    2. 扫描类:编写一个类扫描器,用于扫描指定包下的所有类。可以使用Java反射机制实现。
    3. 实例化对象:对于标注了@MyComponent注解的类,使用反射机制实例化对象并将其添加到IOC容器中。
    4. 依赖注入:对于需要依赖注入的对象,通过反射机制找到对应的依赖并进行注入。可以定义一个@MyAutowired注解用于标注需要进行依赖注入的字段。
    5. 使用IOC容器:在需要使用IOC容器的类中,使用IOC容器获取需要的实例。可以定义一个getBean方法用于从IOC容器中获取实例。

    以上是自定义IOC容器的基本步骤。在实际应用中,还需要考虑异常处理、IOC容器的生命周期管理等问题。