怎么理解Spring中的DI和IOC?

Spring

发展

  • 2002年 Road Johnon 发表
  • 2003年 spring Aop Ioc(控制反转)【DI 依赖注入】
  • 现如今:springmvc 、spring data 、springcloud、springboot 等等Spring家族

初始化Spring

  1. 搭建环境
    1. spring下载网址

    2. 开发Spring至少需要的jar包

      • spring-core
      • spring-beans
      • spring-aop
      • spring-expression
      • spring-context
      • common-logging(第三方日志)
    3. 配置 applicationContext.xml 文件

      
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://www.springframework.org/schema/beans  					  http://www.springframework.org/schema/beans/spring-beans.xsd">
         
      beans>
      

IoC(控制反转) 与 DI(依赖注入)

  • IoC(inversion of Control,控制反转)

    • 为了获取 对象 一般方法为 new object();但是这种方法的弊端是,每次需要创建一个对象即需创建对象。这种方法过于繁琐(为了解耦合),于是引入了简单工厂,每次获取前只需getObject();
    • 于是可将IoC简单一个为超级工厂 ,每次获取对象只需先将对象放入Spring容器中,然后直接通过getObject(),获取即可。
  • DI(dependency injection,依赖注入)

    • 尽管通过以上的解释我们已经大致理解了什么是IoC,但是理解起来仍有些疑惑,于是IoC的另一种解释即为DI(依赖注入)。
    • 将属性值注入给属性,再将属性注入给bean,再将bean注入Spring 容器。获取对象时通过getObject()获取即可;
  • 总结:IoC与DI本质相同,仅仅叫法不同,因为IoC描述起来比较模糊,所以才有了DI这一理解方式

依赖注入的三种方式

  • 依赖注入使用的底层原理是(反射)【反射是框架的灵魂,理解反射对学习框架事半功倍】

  • 为方便理解现有两个类 StuentCourse

    • Sudent
    package cn.spring.bean;
    
    public class Student {
        private int stuNo;
        private String stuName;
        private int age;
    
        public Student() {
        }
    
        public Student(int stuNo, String stuName, int age) {
            this.stuNo = stuNo;
            this.stuName = stuName;
            this.age = age;
        }
    
        public int getStuNo() {
            return stuNo;
        }
    
        public void setStuNo(int stuNo) {
            this.stuNo = stuNo;
        }
    
        public String getStuName() {
            return stuName;
        }
    
        public void setStuName(String stuName) {
            this.stuName = stuName;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "stuNo=" + stuNo +
                    ", stuName='" + stuName + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    • Course
    package cn.spring.bean;
    
    public class Course {
        private String curName;
        private int curScore;
        private Student student;
    
        public Course() {
        }
    
        public Course(String curName, int curScore, Student student) {
            this.curName = curName;
            this.curScore = curScore;
            this.student = student;
        }
    
        public String getCurName() {
            return curName;
        }
    
        public void setCurName(String curName) {
            this.curName = curName;
        }
    
        public int getCurScore() {
            return curScore;
        }
    
        public void setCurScore(int curScore) {
            this.curScore = curScore;
        }
    
        public Student getStudent() {
            return student;
        }
    
        public void setStudent(Student student) {
            this.student = student;
        }
    
        @Override
        public String toString() {
            return "Course{" +
                    "curName='" + curName + '\'' +
                    ", curScore=" + curScore +
                    ", student=" + student +
                    '}';
        }
    }
    
    
    • 测试单元
    package cn.spring.domain;
    
    import cn.spring.bean.Course;
    import cn.spring.bean.Student;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Test {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//获取Ioc容器
            Student student = (Student) context.getBean("student");//获取Student
            System.out.println(student);
            Course course = (Course) context.getBean("course");//获取Course
            System.out.println(course);
        }
    }
    
    
  1. 通过 setXXX() 方式

    • 在applicationContext.xml 中配置 Bean 注入值
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="student" class="cn.spring.bean.Student">
            <property name="age" value="23"/>
            <property name="stuName" value="张三"/>
            <property name="stuNo" value="1"/>
        bean>
        <bean id="course" class="cn.spring.bean.Course">
            <property name="curName" value="Spring"/>
            <property name="curScore" value="4"/>
            <property name="student" ref="student"/>
        bean>
    
    beans>
    
    • 同过全类名 使用反射 拿到类对象,通过类对象生成对象,调用对象的setXXX方法来为对象赋值。(反射原理)上述代码可简单理解为:

      Student student(id) = new Student();
      student.setAge(23);
      student.setStuName("张三");
      student.setStuNo("1");
      
  2. 通过构造器方式

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="student" class="cn.spring.bean.Student">
            <constructor-arg name="stuNo" value="1"/>
            <constructor-arg name="stuName" value="zs"/>
            <constructor-arg name="age" value="23"/>
        bean>
        <bean id="course" class="cn.spring.bean.Course">
            <constructor-arg name="curName" value="Spring"/>
            <constructor-arg name="curScore" value="4"/>
            <constructor-arg name="student" ref="student"/>
        bean>
    
    beans>
    
  3. 通过 P 方式

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p" 
           >
        
        <context:component-scan base-package="cn.spring.bean"/>
    
    beans>
    

    使用注解实现声明式事务

    • 搭建环境
      • spring-tx 事务
      • jdbc.jar 【数据库】
      • commons-dbcp.jar 连接池到数据库
      • commons-pool.jar 连接池
      • spring-jdbc.jar spring 的jdbc
      • aopalliance.jar aop
    • 在方法前加入:
     @Transactional(readOnly = false,propagation = Propagation.REQUIRED)
    ring-tx                      
    

你可能感兴趣的:(Spring框架)