Spring学习之IOC和DI

心已赠人 2022-05-18 00:46 383阅读 0赞

首先我想明确它们之间的关系:

  • IOC:控制反转,把创建对象的过程交给Spring去管理,自己不做任何关注。
  • DI:依赖注入,向Bean里的属性进行设值。
  • DI是不可以自己独立进行工作的,必须要在IOC的基础上完成工作,也可以理解为DI是IOC的一种实现。

什么是IOC?

  • 首先我想谈一下我自己的想法

IOC全名是Inverse Of Control,意思是控制反转,那么这个控制反转到底是什么意思呢?通俗一点可以这样子理解:众所周知,在java程序中,完成每个业务逻辑必须至少需要两个或以上的对象来协助完成。在传统编程中,假设我的程序中存在两个对象A和B,当A需要B的一些帮助,我们必须去手动实例化这个对象(类似new object()这样子的语法),而IOC的思想是:我们可以把对象之间的引用关系交给Spring来管理,对象的创建、维护、销毁等生命周期的这些操作程序人员完全不用自己关注,全权交给Spring容器,其实这样就把控制权交给了Spring,所以就叫做控制反转。

  • Bean的生命周期

在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就说每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象。
这里写图片描述

  • 注入的三种方式

    • 基于XML的bean定义(需要提供setter方法)

首先定义Student和Teacher类。

  1. package com.demo.ioc.Bean;
  2. public class Student {
  3. private String name;
  4. private Teacher teacher;
  5. public String getName() {
  6. return name;
  7. }
  8. public void setName(String name) {
  9. this.name = name;
  10. }
  11. public Teacher getTeacher() {
  12. return teacher;
  13. }
  14. public void setTeacher(Teacher teacher) {
  15. this.teacher = teacher;
  16. }
  17. }
  18. package com.demo.ioc.Bean;
  19. public class Teacher {
  20. private String name;
  21. public String getName() {
  22. return name;
  23. }
  24. public void setName(String name) {
  25. this.name = name;
  26. }
  27. }

bean1.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
  5. <bean id="student" class="com.demo.ioc.Bean.Student">
  6. <property name="name" value="张三"/>
  7. <property name="teacher" ref="teacher"/>
  8. </bean>
  9. <bean id="teacher" class="com.demo.ioc.Bean.Teacher">
  10. <property name="name" value="李四"/>
  11. </bean>
  12. </beans>
  13. package com.demo.ioc.spring;
  14. import org.springframework.context.support.FileSystemXmlApplicationContext;
  15. import com.demo.ioc.Bean.Student;
  16. import com.demo.ioc.Bean.Teacher;
  17. public class Main {
  18. public static void main(String args[]) throws Exception{
  19. FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/bean1.xml");
  20. Student student = (Student) context.getBean("student");
  21. Teacher teacher = (Teacher) context.getBean("teacher");
  22. System.out.println("学生的姓名:"+student.getName()+"。老师是"+student.getTeacher().getName());
  23. System.out.println("老师的姓名:"+teacher.getName());
  24. }
  25. }
  • 基于注解的bean定义(不需要提供setter方法)

    package com.demo.ioc.Bean;

    import javax.annotation.Resource;

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;

    @Component(“student”)
    public class Student {

    1. @Value("张三")
    2. private String name;
    3. @Resource
    4. private Teacher teacher;
    5. public String getName() {
    6. return name;
    7. }

    // public void setName(String name) {
    // this.name = name;
    // }

    1. public Teacher getTeacher() {
    2. return teacher;
    3. }

    // public void setTeacher(Teacher teacher) {
    // this.teacher = teacher;
    // }

  1. }
  2. package com.demo.ioc.Bean;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.stereotype.Component;
  5. @Component("teacher")
  6. public class Teacher {
  7. @Value("李四")
  8. private String name;
  9. public String getName() {
  10. return name;
  11. }
  12. // public void setName(String name) {
  13. // this.name = name;
  14. // }
  15. }

bean2.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. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!--扫描组件的包目录-->
  10. <context:component-scan base-package="com.demo.ioc.Bean"/>
  11. </beans>
  12. package com.demo.ioc.spring;
  13. import org.springframework.context.support.FileSystemXmlApplicationContext;
  14. import com.demo.ioc.Bean.Student;
  15. import com.demo.ioc.Bean.Teacher;
  16. public class Main {
  17. public static void main(String args[]) throws Exception{
  18. FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/bean2.xml");
  19. Student student = (Student) context.getBean("student");
  20. Teacher teacher = (Teacher) context.getBean("teacher");
  21. System.out.println("学生的姓名:"+student.getName()+"。老师是"+student.getTeacher().getName());
  22. System.out.println("老师的姓名:"+teacher.getName());
  23. }
  24. }
  • 基于JavaConfig定义(需要提供setter方法)

    package com.demo.ioc.Bean;

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    @Configuration
    public class BeansConfiguration {

    1. @Bean
    2. public Student student(){
    3. Student student=new Student();
    4. student.setName("张三");
    5. student.setTeacher(teacher());
    6. return student;
    7. }
    8. @Bean
    9. public Teacher teacher(){
    10. Teacher teacher=new Teacher();
    11. teacher.setName("李四");
    12. return teacher;
    13. }

    }

    package com.demo.ioc.spring;

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;

    import com.demo.ioc.Bean.BeansConfiguration;
    import com.demo.ioc.Bean.Student;
    import com.demo.ioc.Bean.Teacher;

    public class Main {

    1. public static void main(String args[]) throws Exception{
    2. AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(BeansConfiguration.class);

    // FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(“src/main/resources/bean2.xml”);

    1. Student student = (Student) context.getBean("student");
    2. Teacher teacher = (Teacher) context.getBean("teacher");
    3. System.out.println("学生的姓名:"+student.getName()+"。老师是"+student.getTeacher().getName());
    4. System.out.println("老师的姓名:"+teacher.getName());
    5. }

    }

  • 容器中Bean的作用域

    • 当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下五种作用域:
  1. singleton: 单例模式,在整个Spring IoC容器中,singleton作用域的Bean将只生成一个实例。
  2. prototype: 每次通过容器的getBean()方法获取prototype作用域的Bean时,都将产生一个新的Bean实例。
  3. request:对于一次HTTP请求,request作用域的Bean将只生成一个实例,这意味着,在同一次HTTP请求内,程序每次请求该Bean,得到的总是同一个实例。只有在Web应用中使用Spring时,该作用域才真正有效。
  4. session:该作用域将 bean 的定义限制为 HTTP 会话。 只在web-aware Spring ApplicationContext的上下文中有效。
  5. global session: 每个全局的HTTP Session对应一个Bean实例。在典型的情况下,仅在使用portlet context的时候有效,同样只在Web应用中有效。

    • 如何实现IOC

      • Spring IOC的实现用到了设计模式:简单工厂模式+反射来实现IoC。
    • BeanFactory和ApplicationContext的区别
      ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,最主要的就是BeanFactory延迟加载,当使用到getBean的时候才会抛异常,而ApplicationContext在刚开始启动加载的时候就会抛出异常,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用ApplicationContext。

什么是DI?

  • 全称为Dependency Injection,意思自身对象中的内置对象是通过注入的方式进行创建。
  • 它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,Spring就是通过反射来实现注入的。
  • 其实我个人觉得IOC和DI是一个东西。

    public static Object newInstance(String className) {

    1. Class<?> cls = null;
    2. Object obj = null;
    3. try {
    4. cls = Class.forName(className);
    5. obj = cls.newInstance();
    6. } catch (ClassNotFoundException e) {
    7. throw new RuntimeException(e);
    8. } catch (InstantiationException e) {
    9. throw new RuntimeException(e);
    10. } catch (IllegalAccessException e) {
    11. throw new RuntimeException(e);
    12. }
    13. return obj;
    14. }

为什么要使用IOC?

在IOC出现以前,组件之间的协调关系是由程序内部代码来控制的,或者说,以前我们使用New关键字来实现两组间之间的依赖关系的。这种方式就造成了组件之间的互相耦合。IoC(控制反转)就是来解决这个问题的,它将实现组件间的关系从程序内部提到外部容器来管理。也就是说,由容器在运行期将组件间的某种依赖关系动态的注入组件中。

发表评论

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

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

相关阅读

    相关 Spring IoCDI

    为什么要有这么多的类注解呢?这与 应用分层 类似,为了在看到类注解后,就能直接了解当前类的用途@Controller:控制层,接收请求,对请求进行处理,并进行响应@Ser...

    相关 Spring IoCDI

    Spring是一个依赖注入(Dependency Injection, DI)和控制反转(Inversion of Control, IoC)容器。IoC意味着应用程序不...

    相关 spring IocDI

    spring的“控制反转”和“依赖注入”,个人看来是一个意思。 传统java程序中,使用一个对象的时候,都需要先new Object()创建一个新对象,才能使用。对象的控制权

    相关 Spring学习IoCDI

           看了两篇讲IoC和DI的文章,实在是讲得太好,有种不知道再怎么写的感觉,终于明白李白为啥说黄鹤楼景色虽好,却因崔颢的题诗在前,无法写诗是啥意思了。两篇文章见下:

    相关 Spring学习IOCDI

    首先我想明确它们之间的关系: IOC:控制反转,把创建对象的过程交给Spring去管理,自己不做任何关注。 DI:依赖注入,向Bean里的属性进行设值。 D