回复“面试手册”,获取本站PDF版
回复“简历”,获取高质量简历模板
回复“加群”,加入程序员交流群
回复“电子书”,获取程序员类电子书
简单来说就是将创建对象的控制权交给Spring框架,IoC是控制反转的意思,这里的控制就是指创建对象的控制权,反转是指将本来在程序中创建对象的权力交给Spring。
如果是初学者,看到IoC这种概念性的描述不是很容易理解这玩意到底是干什么的,又有什么用?
IoC并不是Spring独有的,而是一种思想,IoC主要的优点有两个,降低代码之间的耦合度和集中资源同一管理,简化开发
先举个比较容易理解的例子吧,先看不用IoC的写法,先确定一个简单的场景,学校、年级、班级(简单理解为学校由年级组成,年级由班级组成,班级由学生组成),大概需要三个Class,如下
class School{
private Grade grade;
School(){
this.grade = new Grade();
}
public void printName(){
System.out.println("路人大学");
}
}
class Grade{
private C c; //C表示班级
Grade(){
this.c = new C();
}
}
class C{
private int studentNum;
C(){
this.studentNum = 50;
}
}
将代码运行起来,先new个大学,然后打印大学的名字
class test{
public static void main(String[] args) {
School school = new School();
school.printName();
}
}
输出
路人大学
这时,有人觉得班级的人数写死了,太不方便,要改成可动态修改的,这时需要修改三个类,如下
class School{
private Grade grade;
School(int studentNum){
this.grade = new Grade(studentNum);
}
public void printName(){
System.out.println("路人大学");
}
}
class Grade{
private C c; //C表示班级
Grade(int studentNum){
this.c = new C(studentNum);
}
}
class C{
private int studentNum;
C(int studentNum){
this.studentNum = 50;
}
}
可以看到代码的整体改动还是比较大的,如果是采用IoC的思想写代码是怎样的呢?
class School{
private Grade grade;
School(Grade grade){
this.grade = grade;
}
public void printName(){
System.out.println("路人大学");
}
}
class Grade{
private C c; //C表示班级
Grade(C c){
this.c = c;
}
}
class C{
private int studentNum;
C(){
this.studentNum = 50;
}
}
还是将代码运行起来,如下,和不采用IoC还是有些区别的,分别需要自己创建每个类的对象
class test{
public static void main(String[] args) {
C c = new C();
Grade grade = new Grade(c);
School school = new School(grade);
school.printName();
}
}
输出结果
路人大学
那这么做有什么好处呢?好像代码量还稍微变多了几行,还是上面的问题,如果要把每个班级的人数换成动态的呢?代码如下
class School{
private Grade grade;
School(Grade grade){
this.grade = grade;
}
public void printName(){
System.out.println("路人大学");
}
}
class Grade{
private C c; //C表示班级
Grade(C c){
this.c = c;
}
}
class C{
private int studentNum;
C(int studentNum){
this.studentNum = studentNum;
}
}
写main方法,将代码运行起来
class test{
public static void main(String[] args) {
C c = new C(66);
Grade grade = new Grade(c);
School school = new School(grade);
school.printName();
}
}
可以看到只需要改C这个类就好了,而不是向之前每个类都要改,其实看到这里也很好理解,这是因为这种写法使得类与类之间的耦合性降低了。
在回想之前说的IoC的定义,控制反转,将创建对象的权力从程序中交给Spring,这里是将创建对象的权力从类中交到了main方法中,因为上面说的还没有Spring什么事,只是介绍IoC的思想。
在Spring框架中,mian方法中创建对象的活是由Spring做的,程序员只需要通过Xml或者注解的形式进行配置就行了。
IoC还有一种说法就是DI(Dependency Injection),依赖注入。至于IoC和DI的关系有一种说法是,IoC是一种思想,而DI是IoC的一种实现方式。那什么是依赖注入呢?其实很好理解,就是将你现在需要的对象给你注入进来,比如上述代码中,Grade类中需要C对象,就可以搞个注解或者Xml配置文件,告诉Spring需要C对象,让他创建好了注入进来。
下面就用Spring的Xml方式来配置下上面的代码,这里还需要搞清楚一个bean的概念,什么是bean呢,其实就是Java对象,上面main方法代码中的c、grade、school都可以看成是一个bean,而Spring就负责管理这些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"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="c" class="dao.C">
<constructor-arg value="66"/>
</bean>
<bean id="grade" class="dao.Grade">
<constructor-arg ref="c"/>
</bean>
<bean id="school" class="dao.School">
<constructor-arg ref="grade"/>
</bean>
可以看到每个类都在这里对应着一个bean,并且对每个类的有参构造方法传了相应的参数,这个bean的配置参数也决定了所创建对象的属性。其中bean的可以理解为对象名,class可以理解为该对象是实现的哪个类,constructor-arg可以理解为创建对象时构造函数传的值,可以看到c对象的人数是66,grade对象依赖c对象,school对象依赖grade对象。
其实它们就是对应着如下代码
C c = new C(66);
Grade grade = new Grade(c);
School school = new School(grade);
然后在把main方法改下就可以运行了,主要时加载下上面的这个xml文件,然后直接从spring拿到school对象就可以了,因为都在xml文件中配置好了
class test{
public static void main(String[] args) {
//初始化Spring容器ApplicationContext,加载配置文件
ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
School school = application.getBean(dao.School.class);
school.printName();
}
}
输出
路人大学
上述介绍的依赖注入方法是构造方法注入,还有两种其他的依赖注入方法,后面还会介绍。
其实写到这里,我相信很多小伙伴可能是理解IoC的好处,但spring的好处却没有get到,因为好像配置xml文件也没比自己一个一个new对象省下多少事,其实还会有基于注解的配置方式,使用熟练会使得开发简化挺多,及springboot会更大程度上简化配置。
本站链接:https://www.mianshi.online,如需勘误或投稿,请联系微信:lurenzhang888
点击面试手册,获取本站面试手册PDF完整版