Spring中IOC的理解(通俗易懂版)
·
文章目录
1.IOC提出背景
- 代码书写现状:耦合度太高,我们修改一处代码,往往要修改很多出相关联的代码。
举例如下:当我们在数据层中不满足BookDaoImpl2中提供的方法了,我们写了新的实现类BookImpl,那么当业务层想要调用数据层中的实现方法的时候,我们就要修改 new 的对象。那么引发问题 我们该一处代码,就要修改与其相关联的代码。
-
解决方法:我们在创建对象的时候,不自己创建而是由外部提供对象
-
引出IOC(控制反转)
对象的创建权由程序转移到外部,这种思想叫做控制反转。
2:IOC的核心概念
- 使用对象时候由主动new对象转换成由外部提供对象,此过程中对象的创建权由程序转移到外部,这种思想叫做控制反转
- Spring技术对此提供的实现
- Spring提供了一个容器,称为IOC容器,用来充当IOC思想中的外部
- IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IOC容器中统称为Bean。
3:IOC的实现方式
- DI-依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程叫做依赖注入
下方当中的业务层中代码想要正常运行还需要Book bookDao的实现,那么的话IOC把这种依赖关系也提供给业务层,这个过程叫依赖注入。那么这个注入指的就是属性的注入
4:IOC的入门案例
(1):思路分析
- IOC管理什么(bean对象)
- 如何告知IOC去管理bean对象 —通过配置文件
- 被管理的对象交给IOC容器,如何获取IOC容器?(接口)
- IOC容器得到后,如何获取bean?
(2):代码解析
- IOC管理的对象
这里的话我们还未完成依赖注入,所以还是new了一个mapper的对象
public class bookServiceImp implements bookService {
bookMapper mapper = new bookMapperImp();
@Override
public void add2() {
mapper.add();
}
}
- 告知IOC去管理bean(通过配置文件)
<!-- id:相当于类别名-->
<!-- class:引入的类-->
<bean id = "bookMapperImp" class="com.wyi.mapper.Imp.bookMapperImp"/>
<bean id = "bookServiceImp" class="com.wyi.service.Imp.bookServiceImp"/>
- 获取IOC容器
ApplicationContext是个接口,所以需要用其实现类CPX
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- 获取bean
getBean的参数就是我们在配置文件当中的id;
bookServiceImp imp = (bookServiceImp) context.getBean("bookServiceImp");
5:DI入门案例
(1):思路分析
- 基于IOC管理bean。
- 上方的service中new 的mapper对象是否保留(否)。
- Service需要的mapper对象如何进入Service中 (通过提供方法)。
- Service和mapper之间该如何联系。
(2):代码解析
- Service需要的mapper对象如何进入Service中 (通过提供方法)
public class bookServiceImp implements bookService {
bookMapper mapper;
@Override
public void add2() {
mapper.add();
}
//提供set方法
public void setMapper(bookMapper mapper) {
this.mapper = mapper;
}
}
- Service和mapper之间的联系
<!-- id:相当于类别名-->
<!-- class:引入的类-->
<bean id = "bookMapperImp" class="com.wyi.mapper.Imp.bookMapperImp"/>
<bean id = "bookServiceImp" class="com.wyi.service.Imp.bookServiceImp">
<!-- property:表示的是配置当前bean的属性-->
<!-- name:表示当前bean的属性名称-->
<!-- ref:参照哪一个bean
ref:bean对象的属性是引用类型,value:bean对象的属性是基本类型 -->
<property name="mapper" ref="bookMapperImp"/>
</bean>
- 那么ioc如何调用set方法呢?
这个时候它就会通过反射来创建对象
调用的是无参构造方法,就算构造器私有也可以调用
然后读取到property标签中对应的属性值
比如说,读取到标签的name属性值为mapper,参照bookMapperImp类 (如果属性是不是对象的话 那么就是 value)
这个时候,IOC就会调用对应的set方法为这个属性赋值(将上方读取到的 属性值 set(bookMapperImp) 进去,为 BookServiceImp提供mapper对象)
如果我们写的实体类中没有提供对应的set方法,那么就会报错。
6:DI依赖注入的方式
(1):前言
所谓注入也就是属性的注入,我们根据bean.xml中bean对象中属性的添加方式 对应不同依赖注入方式,在某个bean中其可能需要用到其他实体类作为属性,那么此时也不用自己new,IOC容器给你提供,那么如何提供呢?那就是这个bean你得给IOC容器一个入口 即 set方法 或者构造器方法
(2):Set方式注入
- bean当中属性的添加
这里属性的添加方式是 property
<bean id = "bookServiceImp" class="com.wyi.service.Imp.bookServiceImp">
<property name="mapper" ref="bookMapperImp"/>
</bean>
- IoC如何注入这个属性呢
我们先通过获取到的IOC容器,然后再通过IOC容器获取到Bean,然后底层是通过反射创建这个bean对象,然后这个bean当中可能存在一些依赖关系,那么的话这个时候IOC容器会调用set方法对这些属性进行注入。
public void setMapper(bookMapper mapper) {
this.mapper = mapper;
}
(3):构造器注入
- bean.xml配置文件
属性的添加方式是 constructor
<bean id = "bookServiceImp" class="com.wyi.service.Imp.bookServiceImp">
//这里的name是我们构造方法中的参数名
<constructor-arg name = "mapper" ref="bookMapperImp"/>
</bean>
- IOC如何注入这个属性呢?
通过构造器注入这个属性,我们配置文件中将mapper这个属性的添加方式提供了,那么接下来就是IOC容器调用构造方法将bean.xml文件中的属性注入到bookServiceImp
public class bookServiceImp implements bookService {
private bookMapper mapper;
public bookServiceImp(bookMapper mapper) {
this.mapper = mapper;
}
}
(4):依赖的自动装配
-
概念:IOC容器根据bean所依赖的资源在容器中自动查找 并注入到bean的过程叫做 自动装配
-
bean.xml 那么这个里头的话 我们就不要再写 property 因为我们是自动查找依赖 一般使用的是按类型
<bean id = "bookMapperImp" class="com.wyi.mapper.Imp.bookMapperImp"/>
<bean id = "bookServiceImp" class="com.wyi.service.Imp.bookServiceImp" autowire="byType"/>
- bean中
也是需要为IOC中提供一个接口来将 这个属性注入进去 这个接口是set方法
private bookMapper mapper;
@Override
public void add2() {
mapper.add();
}
public void setMapper(bookMapper mapper) {
this.mapper = mapper;
}
- 自动装配注意事项
自动装配用于引用类型依赖注入,不能对简单类型进行操作
使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
7:注解开发模式的依赖注入
(1):前言介绍
我们以前是需要用bean.xml,在其中我们需要写配置bean,那么现在我们改用注解了,想要添加那个bean对象,就在那个类上加上注解。
- @Component
@Component的衍生注解(衍生的注解跟@Component注解作用相同) - @Service
- @Controller
- @Repository
(2):注解模式的依赖注入(单指自动装配)
这里我们只需要在相关联的bean上添加注解@Autowired 那么IOC容器就会扫描容器中的bean,(被扫描的bean就是用@component注解或者衍生注解修饰的bean)
更多推荐
已为社区贡献4条内容
所有评论(0)