一.什么是控制反转
首先我们可以回想一下平时写代码时是如何创建对象,比如说有一个类是People,那么我们在创建对象时需要的是如下操作:
People people = new People();
这是我们手动创建。那么控制反转就是把操作对象的调用权交给容器,容器会负责对象的装配和管理。我们不需要手动new对象,只需要声明即可,即由IOC容器来控制对象的创建。
二.控制反转优点
- 减少耦合:通过将依赖关系的控制权交给外部容器,组件之间的耦合度降低。这使得组件更容易测试、维护和替换。
- 更好的可测试性:控制反转使得依赖关系更容易模拟和替代。这使得单元测试和集成测试更容易进行。
- 更好的可扩展性:通过将依赖关系解耦,应用程序更容易扩展。新的组件可以更容易地添加到应用程序中,而不需要修改现有的代码。
- 更好的可维护性:通过集中管理依赖关系,应用程序的配置更容易维护。这使得应用程序更具可维护性。
三.IOC和DI的关系
其实DI 是 IOC 的一种具体实现方式,它指的是将对象所依赖的其他对象(即依赖)通过构造函数、Setter 方法或其他方式注入到对象中,从而消除了对象之间的耦合关系。
下面我会介绍到三种注入方式:set注入,构造器注入,自动注入。
四.IOC的实现
先自行创建一个项目,然后在pom.xml的<dependencies>中导入下面依赖:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency>
导入依赖后可以查看一下是否成功,如果你想使用其他版本可以自行加<version>
4.1 基于xml配置实现
为了方便演示,我没有写接口,直接定义了bookdao,bookservice和一个测试类。
这是没有使用IOC时的代码,里面内容也很简单:
运行结果如下:
那么接下来就要使用IOC容器来控制对象创建。根据小案例,我们可以看出要使用bookdao和bookservice两个类来new对象,所以IOC需要管理这两个类,那么如何管理呢?
这时候我们就需要把它们配置成bean。
首先在resources文件夹下创建一个xml配置文件,我这里命名为spring.xml。
将如下代码复制到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>
我们需要在<beans>中配置bean。下图是我配置的bean,大家根据自己情况配置。
配置好之后我们就可以改Test类了。
运行结果:
可以看到我们配置成功了。
到这一步我们会发现,其实在bookservice中还有一个手动创建的对象,dao层调用了service中的方法。那么我们需要的是确定两个bean的关系,并且使用方法让dao对象进入service中。
这里就涉及到了依赖注入,我们需要注入的是bookdao对象。
4.1.1使用set注入
我们需要修改bookservice类中方法,入下图:
接下来就是处理两个bean之间的关系。我们只需要搞清楚是在bookservice类中创建一个bookdao对象即可。
那么我们需要在bookservice<bean>中写<property>标签来配置。如下图:
这就算是配置完成,运行结果如下:
4.1.2使用构造器注入
使用构造器注入思路和set注入基本一样,只不过需要使用构造函数,如下图:
同样xml文件也需要修改,如下图:
运行结果如下:
4.1.3自动注入
相比于前两个,自动注入可以说是很简单了,我们需要一个set函数,对于xml只需要配置<bean>中的autowried属性即可,如下图:
运行结果如下:
4.2基于注解实现
注解实现可以说是我们以后经常用到的,相比于xml配置的代码量是非常少的,方便不少。
接下来我介绍几个注解:
- @Component: 标注一个类为Spring容器的Bean,
- @Controller: 用于controller控制器层
- @Service: 用于service服务层
- @Repository : 用于dao持久层
虽说是四个,其实和一个没有区别,因为@controller,@service,@repository是由@component衍生出来的,他们的作用基本一样。
除此之外,我们还要省略掉xml配置文件,这时候就要选择新注解代替配置文件的功能。
- @Configuration 使用于配置类上,可以代替配置文件
- @ComponentScan() 用于实现spring注解扫描,会扫描特定包内的类上的注解。
介绍完注解之后我们就开始小案例,首先在原有的基础案例上添加一个配置类,如下图:
同时使用注解表明他是配置类,并且设置扫描的路径,我设置的是com.example.ioc下所有。
然后给其他类添加注解,如下图:
service后面的()内容相当于配置文件的id
最后是测试文件的编写,如下图:
运行结果如下图:
五.结束
本次小案例只是为了入门,让大家基本有一个概念,虽然后续不会怎么使用配置文件实现,但是也需要了解其原理。