什么是Spring的IoC,依赖注入又该怎么实现?

港控/mmm° 2023-10-14 20:14 103阅读 0赞

什么是IoC

所谓的控制反转(Inversion of Control),缩写为IoC,其实就是把对象的创建和对象之间的依赖关系处理,交给 Spring容器来管理,不用程序员自己创建和维护的一种技术。我们使用IoC的目的,主要是为了降低类之间的耦合。

IoC的底层原理

IoC的底层原理主要是基于xml解析+工厂模式+反射等技术进行实现。

  • xml解析:基于xml,配置好要创建的Javabean对象;
  • 工厂模式:把对类的创建初始化等工作,全都交给一个工厂来执行;
  • 反射:使用反射技术创建xml中配置的bean。

IoC模拟实现

为了让大家更好地理解IoC的工作原理,接下来我们自己简单模拟一下Spring IoC的底层实现原理。

第一步:我们先准备一个属性文件beans.properties,我这里使用属性文件代替xml的文件功能。

  1. dept=com.qfedu.pojo.Dept
  2. emp=com.qfedu.pojo.Emp

第二步:编写工厂类QfBeanFactory.java

  1. /**
  2. * 模拟spring 容器的工厂类
  3. */
  4. public class QfBeanFactory {
  5. private static Properties properties = new Properties();
  6. //该map相当于spring容器,用来存储创建好的bean对象
  7. private static Map<String, Object> ioc = new HashMap<String, Object>();
  8. static {
  9. try {
  10. properties.load(BeanFactory.class.getClassLoader().getResourceAsStream("beans.properties"));
  11. //获取所有属性名
  12. Set<String> names = properties.stringPropertyNames();
  13. System.out.println(names);
  14. //通过反射技术创建属性文件里配置的要创建的bean开始
  15. for (String name : names) {
  16. //获取全类名
  17. String clsName= (String) properties.get(name);
  18. Class clazz=Class.forName(clsName);
  19. if (!Objects.isNull(clazz)){
  20. //反射构建对象
  21. Object object=clazz.getConstructor().newInstance();
  22. // 存储到map中
  23. ioc.put(name,object);
  24. }
  25. }
  26. //通过反射技术创建属性文件里配置的要创建的bean结束
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. /**
  32. 通过属性文件中属性名(类似spring配置文件中的bean的id)获取工厂创建好的对象
  33. */
  34. public static Object getBean(String beanName){
  35. return ioc.get(beanName);
  36. }
  37. }

代码解释:

  • 工厂类中的静态代码块实现读取属性文件中的配置信息;
  • 根据读到的配置信息,使用反射技术构建bean对象;
  • 然后将构建好的对象放到map中;
  • 通过提供的getBean方法,获取工厂中创建好的bean对象。

第三步:我们再编写一个测试类:

  1. public class IocTest{
  2. public static void main(String[] args) {
  3. Dept dept= (Dept)QfBeanFactory.getBean("dept");
  4. System.out.println(dept);
  5. Emp emp= (Emp)QfBeanFactory.getBean("emp");
  6. System.out.println(emp);
  7. }
  8. }

经过以上测试我们可以获得创建好的dept和emp对象,以上我们模拟了spring ioc的原理。

bean对象的创建

接下来我们再来看看Spring框架又是怎么创建和使用bean对象的。

4.1 创建spring-bean.xml配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. https://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <bean id="dept" class="com.qfedu.pojo.Dept"></bean>
  7. <bean id="emp" class="com.qfedu.pojo.Emp"></bean>
  8. </beans>

4.2 加载配置文件获得Spring IoC容器

  1. ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-bean.xml");

4.3 通过spring容器获取dept、emp 对象

  1. Emp emp= (Emp) applicationContext.getBean("emp");
  2. System.out.println(emp);
  3. Dept dept= (Dept) applicationContext.getBean("dept");
  4. System.out.println(dept);

4.4 小结

最后我们再总结一下Spring创建bean对象的过程。

  • spring-bean.xml相当于

    beans.properties;

  • ClassPathXmlApplicationContext就相当于QfBeanFactory;
  • getBean 方法相当于QfBeanFactory中的getBean。

其中ClassPathXmlApplicationContext类的结构图如下所示:

图片

通过以上类结构图,我们可以看出ClassPathXmlApplicationContext的最顶层就是BeanFacorty工厂,而ClassPathXmlApplicationContext则是一个具体的实现类。BeanFacorty有很多实现类,其中ClassPathXmlApplicationContext、AnnotationConfigApplicationContext则是比较常用的具体子类。

图片

BeanFactory以Factory结尾,表示这是一个工厂类(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括实例化、定位、配置应用程序中的对象及建立这些对象间的依赖等。BeanFactory只是个接口,并不是IoC容器的具体实现,所以Spring容器给出了多种实现,如 ClassPathXmlApplicationContext、AnnotationConfigApplicationContext、ApplicationContext等。

现在你知道Spring是怎么实现IoC的了吗?如果你还有什么疑问,可以在评论区留言哦。关注千锋官方博客,干货天天都不断哦!

发表评论

表情:
评论列表 (有 0 条评论,103人围观)

还没有评论,来说两句吧...

相关阅读

    相关 什么依赖注入Ioc容器了

    背景 在很多编程语言(例如java)开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,