自定义IOC的实现: 没有使用IOC技术的环境: 1.创建工程customIoc,添加依赖(需要添加解析xml的依赖): <?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.it</groupId> <artifactId>customIoc</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- 解析 xml 的 dom4j --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <!-- dom4j 的依赖包 jaxen --> <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1.6</version> </dependency> <!--单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project> 2.三层框架模拟: 2.1 web层 package com.it.web; import com.it.service.UserService; import org.junit.Test; /** * ToDo * @author Lyle * @date 2020/9/5 */ public class UserServlet { @Test public void doGet(){ //获取请求参数 //调用业务 UserService userService = new UserService(); userService.test(); //响应结果 } } 2.2 service层 package com.it.service; import org.junit.Test; /** * ToDo * * @author Lyle * @date 2020/9/5 */ public class UserService { /** * 注册 */ public void test(){ System.out.println("调用UserDao中的save方法。。。。"); } } 2.3 dao层:接口+实现类 public interface UserDao { void save(); } public class UserDaoImpl implements UserDao { public void save(){ System.out.println("save方法保存"); } } 使用IOC技术: IOC实现:xml+工厂模式+反射 1.xml配置:applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans> <!--id属性,作为bean的惟一标识,一般写接口或者类的名字,首字母小写; class属性:写类的全路径名--> <bean id="userDao" class="com.it.dao.impl.UserDaoImpl"> </bean> </beans> 2.工厂对象:BeanFactory 工厂对象解析xml,获取类的全路径名,然后通过反射创建对象,存入Map容器中; 简单版: 缺点: 每次getBean都需要读取文件; 临时使用的时候才使用反射创建(反射的效率比new要慢) package com.it.utils; import org.dom4j.*; import org.dom4j.io.SAXReader; import java.io.IOException; import java.io.InputStream; /** * ToDo * * @author Lyle * @date 2020/9/6 */ public class BeanFactory { public static Object getBean(String id){ InputStream is=null; try { //1.创建SAXReader对象 SAXReader saxReader = new SAXReader(); //2.读取xml,获得document对象 //获取文件流对象 is = BeanFactory.class.getClassLoader().getResourceAsStream("applicationContext.xml"); Document document = saxReader.read(is); //3.根据id获得bean标签 Element beanEle = (Element) document.selectSingleNode("//bean[@id='"+id +"']"); //4.获得bean标签的class属性值 String className = beanEle.attributeValue("class"); //System.out.println(className); //5.根据class属性值(类的全路径名)通过反射创建对象返回 Class clazz = Class.forName(String.valueOf(className)); Object obj = clazz.newInstance(); return obj; } catch (Exception e) { e.printStackTrace(); return null; }finally { if (is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* public static void main(String[] args) { BeanFactory.getBean("userDao"); }*/ } 获取对象时通过这个工厂对象的静态方法获取对象: UserDao userDao= (UserDao) BeanFactory.getBean("userDao"); 终极版: 将读取文件放入静态代码块,只读取一次; 程序初始化的时候,创建好对象放入Map容器中,使用时直接从Map容器中获取; package com.it.utils; import org.dom4j.*; import org.dom4j.io.SAXReader; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; /** *SpringIOC 工厂对象:读取和解析xml,通过反射创建对象存入Map容器中 * @author Lyle * @date 2020/9/6 */ public class BeanFactory { //Map容器 public static Map<String,Object> beanMap=new HashMap<>(); //静态代码块,解析xml,反射创建对象存入Map容器中 static { InputStream is=null; try { //1.创建SAXReader对象 SAXReader saxReader = new SAXReader(); //2.读取xml,获得document对象 //获取文件流对象 is = BeanFactory.class.getClassLoader().getResourceAsStream("applicationContext.xml"); Document document = saxReader.read(is); //获得所有的bean标签,遍历创建好对象存入Map容器中 List<Element> baenEles = document.selectNodes("//bean"); //遍历 for (Element baenEle : baenEles) { //获得bean标签的id和class属性值 String id = baenEle.attributeValue("id"); String className = baenEle.attributeValue("class"); //根据class属性值,通过反射创建好对象存入Map中 Object clzss = Class.forName(className).newInstance(); beanMap.put(id,clzss); } } catch (Exception e) { e.printStackTrace(); }finally { if (is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static Object getBean(String id){ return beanMap.get(id); } }