2-形象理解SpringIOC(控制反转)

Posted kesheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2-形象理解SpringIOC(控制反转)相关的知识,希望对你有一定的参考价值。

通过一个学生选择课程的demo 以3中不同的实现方式理解一下springIOC,体会IOC的好处:

声明一个ICourse接口:

package org.ks.newinstance;

public interface ICourse {
    void learn();        //学习。。。。
}

两个ICourse接口的实现类:JavaCourse.java  ,   htmlCourse.java

package org.ks.newinstance;

public class JavaCourse implements ICourse {

    @Override
    public void learn() {
        System.out.println("学习Java");
    }
    
}
package org.ks.newinstance;

public class HtmlCourse implements ICourse {

    @Override
    public void learn() {
        System.out.println("学习HTML");
    }
    
}

学生实体类:Student

package org.ks.entity;

import org.ks.factory.CourseFactory;
import org.ks.newinstance.HtmlCourse;
import org.ks.newinstance.ICourse;
import org.ks.newinstance.JavaCourse;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Student {
    private int stuNo;
    private String stuName;
    private int stuAge;
    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 getStuAge() {
        return stuAge;
    }
    public void setStuAge(int stuAge) {
        this.stuAge = stuAge;
    }
    @Override
    public String toString() {
        return this.stuName + "," + this.stuAge + "," + this.stuNo;
        }
    
    //学习所有课程
    public void learn(String name)
    {
        /*
        //方式2.
            //从自己编写的简单工厂中国获取课程
        ICourse course = CourseFactory.getCourse(name);//course就是根据name拿到的相应课程
        course.learn();
        */

        //方式3.
        //直接从IOC容器中获取
        //从SpringIOC提供的超级工厂中获取课程(前提:之前设置过Bean)
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ICourse course = (ICourse)context.getBean(name);
        course.learn();
        
    }
    
    //方式1.
    public void learnjava() {         //学习Java课程
        ICourse course = new JavaCourse();
        course.learn();
    }
    
    //学习HTML课程
    public void learnhtml() {
        ICourse course = new HtmlCourse();
        course.learn();
    }
}

模拟的工厂(用于产生课程):

package org.ks.factory;

import org.ks.newinstance.HtmlCourse;
import org.ks.newinstance.ICourse;
import org.ks.newinstance.JavaCourse;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

//课程工厂(用于产生课程)
public class CourseFactory {
    public static ICourse getCourse(String name)//getCourse声明为静态方法,可以通过类名直接调用
    {
        
        //方式2.
        if(name.equals("java"))
        {
            return (ICourse)new JavaCourse();
        
        }else
        {
            return (ICourse)new HtmlCourse();
        }
        
        
        
        /*
        //方式3.
        //获取IOC容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        if(name.equals("java"))
        {
            return (ICourse)context.getBean("JavaCourse");     // new -> 从 IOC获取
        }
        else if(name.equals("html"))
        {
            return (ICourse)context.getBean("HtmlCourse");      // new -> 从 IOC获取
        }
        */
    }
}

配置文件: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">

    <!-- 该文件中所产生的所有对象,被spring放入了一个称之为spring IOC 容器的地方 -->
    <!-- id:唯一标识符  class:指定类型 -->
    <bean id = "student" class = "org.ks.entity.Student">  <!-- 相当于:Student stu = new Student() -->
        <!-- property:该class代表的类的属性
            name:属性名
            value:属性值
         -->
        <property name="stuName" value = "李四"></property>
        <property name="stuAge" value = "20"></property>
        <property name="stuNo" value = "13"></property>
    </bean>
    
    <bean id = "JavaCourse" class = "org.ks.newinstance.JavaCourse">
        
    </bean>
    
    <bean id = "HtmlCourse" class = "org.ks.newinstance.HtmlCourse">
        
    </bean>
</beans>

入口:

package org.ks.test;

import org.ks.entity.Student;
import org.ks.factory.CourseFactory;
import org.ks.newinstance.ICourse;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test2 {
    //方式1.
    public static void learnCourse()
    {
        Student stu = new Student();
        stu.learnjava();
        stu.learnhtml();
    }
    
    //方式2.
    public static void learnCourseWithFactory()
    {
        Student stu = new Student();
        stu.learn("html");
    }
    
    //方式3.
    public static void learnCourseWithIOC()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //执行从springioc容器中获取一个id为student的对象
        Student stu = (Student)context.getBean("student");  //new Student() 变成  从IOC获取student
        stu.learn("HtmlCourse");
    }
    
    public static void main(String[] args) 
    {
        //learnCourse();           //方式1.直接通过创建Student对象的方式
        //learnCourseWithFactory();         //方式2.自己设置建档工厂的方式
        learnCourseWithIOC();          //方式3.通过SpringIOC(超级工厂)的方式
    } 
}

总结:

IOC:控制反转(将创建对象,属性值 的方式进行了反转,从 new,setXxx() 反转为了 从springIOC容器中 getBean() )

IOC也可以称之为DI(依赖注入)
依赖注入:将属性值注入给了属性,将属性注入给了Bean,将Bean注入给了IOC容器。(形象理解:社会主义)

因此:IOC/DI,无论要什么对象,都可以直接去springIOC容器中获取,而不需要自己操作(new/setXxx()....)
           所以IOC分为两步:1.先在springIOC中存放对象并赋值     2.获取对象

以上是关于2-形象理解SpringIOC(控制反转)的主要内容,如果未能解决你的问题,请参考以下文章

SpringIOC

SpringIoc之初了解

轻松了解Spring中的控制反转和依赖注入

Spring IoC的形象化理解

spring依赖注入,和控制反转。用自己的话说是怎么说的。最好能够用代码来解释

spring 控制反转怎么体现