2. Spring解耦合、控制反转、依赖注入(IOC)

2. Spring解耦合、控制反转、依赖注入(IOC)

耦合度高的代码

以下为未使用spring的代码:

/**
 * 	 学生信息类
 */
public class Student {
	private int stuno;   //学号
	private String stuName = null;  //姓名
	private int stuAge;   //年龄
	
	
	
	/**
	 * 	学习课程
	 */
	public void learnJava() {
		ICourse course = new JavaCourse();
		course.learn();
	}
	
	public void learnHtml() {
		ICourse course = new HtmlCourse();
		course.learn();
	}
}

/**
  *	 学习课程的接口
  */
public interface ICourse {
	public void learn(); //学习...
}



/**
 *	学Html课程 实现类
 * @author ASUS
 *
 */
public class HtmlCourse implements ICourse{

	@Override
	public void learn() {
		// TODO Auto-generated method stub
		System.out.println("学习Html课程");
	}
	
}

/**
 *	学java课程 实现类
 * @author ASUS
 *
 */
public class JavaCourse implements ICourse{

	@Override
	public void learn() {
		// TODO Auto-generated method stub
		System.out.println("学习java课程");
	}
	
}

/**
 * 测试类
 * @author ASUS
 *
 */
public class Test {
	private static final String Student = null;
	/**
	  * 创建学生学习课程 方法
	  */
	public static void learnCourse() {
		Student student = new Student();
		student.learnHtml();
		student.learnJava();
	}

	/**
	 * 	测试
	 * @param args
	 */
	public static void main(String[] args) {
		learnCourse();
	}
}

这种方式看起来非常合理,但是在对象创建的过程中是分散的,如果学习的课程增多,那么管理起来会异常的复杂.

下图是这一串代码的关系草图:

image-20200917215408686

解决方式

解决方式一(简单工厂):

  • 使用简单工厂来集中对象的创建(草图):

  • image-20200917215801233

  • 代码

    /**
     * 	学习某门课程的接口
     * @author ASUS
     *
     */
    public interface ICourse {
    	public void learn(); //学习...
    }
    
    /**
     *	学java课程
     * @author ASUS
     *
     */
    public class JavaCourse implements ICourse{
    
    	@Override
    	public void learn() {
    		// TODO Auto-generated method stub
    		System.out.println("学习java课程");
    	}
    	
    }
    
    /**
     *	学Html课程
     * @author ASUS
     *
     */
    public class HtmlCourse implements ICourse{
    
    	@Override
    	public void learn() {
    		// TODO Auto-generated method stub
    		System.out.println("学习Html课程");
    	}
    	
    }
    
    /**
     * 	课程工厂
     */
    import org.yibinxueyuan.newinstance.HtmlCourse;
    import org.yibinxueyuan.newinstance.ICourse;
    import org.yibinxueyuan.newinstance.JavaCourse;
    
    public class CourseFactory {
    	public static ICourse getCourse(String name) {
    		if("java".equals(name)) {
    			return new JavaCourse();
    		}else if("Html".equals(name)) {
    			return new HtmlCourse();
    		}else {
    			return null;
    		}
    	}
    }
    
    /**
     * 	 学生信息类
     */
    public class Student {
    	private int stuno;   //学号
    	private String stuName = null;  //姓名
    	private int stuAge;   //年龄
    	
    	
    	/**
    	 * 	学习任何课程
    	 */
    	public void learn(String name) {
    		ICourse course = null;
    		course = CourseFactory.getCourse(name);
    		course.learn();
    	}
        /**
     * 测试类
     * @author ASUS
     *
     */
    public class Test {
        /**
    	 * 	 使用工厂方法来让学生学习课程
    	 */
    	public static void learnCourseWithFactory() {
    		Student student = new Student();
    		student.learn("java");
    		student.learn("Html");
    	}
    	
    	/**
    	 * 	测试
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		learnCourseWithFactory();
    	}
    }
    
    
  • 弊端:工厂需要自己建立,多了一些步骤

解决方式二(Spring IOC):

  • 使用spring IOC 来解决,springIoc相当于一个超级工厂,直接调用就行,不需要自己手动写

  • 草图:

    image-20200917223052697

  • 代码:

    /**
     * 	 学生信息类
     */
    public class Student {
    	private int stuno;   //学号
    	private String stuName = null;  //姓名
    	private int stuAge;   //年龄
    	
    	
    	/**
    	 * 	学习任何课程
    	 */
    	public void learn(String name) {
    		//使用springIOC来创建对象
    		ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
    		ICourse course = (ICourse)context.getBean(name);
    		course.learn();
    	}
    }
    
    
    /**
     * 测试类
     * @author ASUS
     *
     */
    public class Test {
    
    	
    	/**
    	 * 	
    	 * 	使用springioc来创建对象
    	 */
    	public static void learnCourseWithFactory() {
    		// 使用springIOC来让学生课程
    		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    		Student student = (Student)context.getBean("student");
    		student.learn("java");
    		student.learn("Html");
    	}
    	
    	
    	
    	/**
    	 * 	测试
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		learnCourseWithFactory();
    	}
    }
    
    

    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">
    	
        
        <bean id = "student" class = "org.yibinxueyuan.entity.Student">
    	</bean>
    	<bean id = "java" class = "org.yibinxueyuan.newinstance.JavaCourse">
    	</bean>
    	<bean id = "Html" class = "org.yibinxueyuan.newinstance.HtmlCourse">
    	</bean>
    
    </beans>
    
    

Spring IOC(控制反转,依赖注入)

通过以上实例,能够感受到SpingIOC的方便,下面是具体概念

  • IOC就是控制反转,

    DI就是依赖注入,两者本身是一种东西

  • 控制反转: 将创建对象、属性值的方式,进行的反转

    未使用ioc的时候是在java程序中进行对象的创建和赋值,主动权在程序(死的)和程序员(用户需求更改的话,改代码要被累死的)手上. 关键点是程序 创建 对象

    使用ioc后,是在xml配置文件中进行对象的创建和赋值,主动权在用户(用户需要什么就怎么改)手中,而程序只需要从配置文件(IOC)中获取对象和对象属性值就可以了.关键点是 程序 对象

  • 依赖注入: 将属性值注入给了属性,将属性注入给了bean,将bean注入给了IOC容器

  • 控制反转和依赖注入本质上是统一种东西的两种不同的理解(第二种更为明确)

posted on 2020-09-21 23:54  夜for星空  阅读(166)  评论(0)    收藏  举报