怎么理解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的核心jar>
      • spring-beans <spring的beans>
      • spring-aop
      • spring-expression
      • spring-context
      • common-logging(第三方日志)
    3. 配置 applicationContext.xml 文件

      <?xml version="1.0" encoding="UTF-8"?>
      <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 注入值
    <?xml version="1.0" encoding="UTF-8"?>
    <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. 通过构造器方式

    <?xml version="1.0" encoding="UTF-8"?>
    <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 方式

    <?xml version="1.0" encoding="UTF-8"?>
    <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" <!-- 使用p需要引入 -->
           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" p:age="23" p:stuName="zs" p:stuNo="1">
    
        </bean>
        <bean id="course" class="cn.spring.bean.Course" p:curName="Spring" p:curScore="4" p:student-ref="student">
    
        </bean>
    
    </beans>
    
  4. 自动装配(只能用于 引用类型)(约定 > 配置)

    • autowire=" Type " Type参数:
      • default
      • byName 通过ID
      • byType 通过参数类型
      • constructor 通过构造器
      • no
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
           default-autowire="byName"  <!--  全局默认装配 -->
           >
    
        <bean id="student" class="cn.spring.bean.Student" 
              autowire="byName" <!-- 局部装配优先级大于全局装配 --> 
    	>    
        </bean>
    
        
    </beans>
    

使用注解定义Bean

  • 通过注解的形式将 bean 及相应的属性值 放入 IoC容器中
  • 使用注解: @ component( component : 组件 (范围大))
  • 注解的细分:
    • @service 服务
    • @Repository 仓库(Dao)
    • @controller 控制
@Repository("student")
public class Student {
    private int stuNo;
    private String stuName;
    private int age;
}

​ 我们可以看见我们在 类 上 使用了 @Repository(仓库)来将 bean 放入IoC容器中,后面 student 是bean的 id

作用等效与:在XMl中:

<bean id="student" class="cn.spring.bean.Student" >
  • 仅仅在 类 上使用 @Repository() 还不能将 bean 真正放入 IoC 容器中,需要在XMl中配置 扫描
<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:context="http://www.springframework.org/schema/context"<!-- 首先导入context -->
       >
    <!-- 扫描 cn.spring.bean 包下类,若类上有 @Repository 则将该类加入 IoC 容器-->
    <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                      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值