核心概念
# 核心概念
- IoC/DI
- IoC容器
- Bean
# 问题
![[Pasted image 20220611171318.png]]
首先我们从图中分析出,业务层某个实现类依赖于数据层的BookDaoImpl
的实现,某天项目经理要求你换个实现类例如BookDaoImpl2
,那么你业务层代码是不是也必须动?
当你变动业务层代码,那是不是又要重新编译代码并且重新测试、部署、发布???
- 代码书写现状
- 耦合度偏高
- 解决方法
- 使用对象时,在程序中不要主动使用new产生对象,而是由外部提供对象。
- 这种思想就被称为IoC 控制反转
- 对象创建控制权交给外部
- 目的:业务层和数据层解耦
# IoC
Spring技术对IoC思想进行了实现
- Spring 提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部”
- IoC容器需要管理大量的对象,包含创建及初始化过程
- 被创建或被管理的对象在IoC容器里被称为Bean
# DI
在容器中建立bean与bean之间的依赖关系的过程,称为依赖注入 ![[Pasted image 20220611172538.png]]
既然IoC容器管理所有对象,那么此时业务层需要依赖数据层对象,IoC容器一不做二不休,干脆帮你把依赖也搞好了
# Spring IoC入门案例
目录结构: ![[Pasted image 20220611173104.png]]
要在maven的pom.xml中依赖spring-context
配置Bean 这一步主要是告知IoC要管理哪个类,以及其他类如何获取到这个类的对象。 首先现在
resource
目录下创建Spring config
类型的applicationContext.xml
,文件名称可以随意设置。然后再配置Bean<bean id="userDaoImpl" class="com.project.dao.impl.UserDaoImpl"/>
这条配置中,class代表哪个类要被管理,id代表其他类如何调用他。获取IoC容器 我们已经将类托管给IoC了,那么如何使用IoC呢?
//主类
public class UserDaoDemo {
public static void main(String[] args) {
// 获得IoC容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获得Bean
UserDao ud = (UserDao) ac.getBean("userDaoImpl");
ud.save(); //该方法是属于UserDaoImpl类中的,会打印一个Hello World。
}
}
2
3
4
5
6
7
8
9
10
那么有好事儿的金针菇就要问了,这个ApplicationContext ac = xxxxx
也太频繁了吧,不如封装一个Util类更好?那这就随你便了。
# Spring DI入门案例
思路分析
- 基于IoC管理Bean
- Service中使用new形式创建Dao对象是否保留?(否)
- Service中需要的Dao对象如何进入到Service中?(提供方法)
- Service与Dao间的关系如何描述?(配置)
这是未更改的UserServiceImpl
public class UserServiceImpl implements UserService{
UserDao ud = new UserDaoImpl();
@Override
public void save() {
System.out.println("UserServiceImpl printer!");
ud.save();
}
}
2
3
4
5
6
7
8
我们需要去除new对象,但去除后会报空指针异常,那么我们如何给他对象呢? 我们可以使用set方法,此时代码应为
public class UserServiceImpl implements UserService{
UserDao ud; //下面propterty中name的值
public void setUd(UserDao ud) {
this.ud = ud;
}
@Override
public void save() {
System.out.println("UserServiceImpl printer!");
ud.save();
}
}
2
3
4
5
6
7
8
9
10
11
12
13
然后我们去修改applicationContext.xml
中的配置
<bean id="userServiceImpl" class="com.project.service.impl.UserServiceImpl">
<property name="ud" ref="userDaoImpl"/>
</bean>
2
3
由于是UserServiceImpl
依赖UserDao
因此需要在UserServiceImpl
的bean底下配置。
<property>
的name代表UserServiceImpl中未指定的ud,而ref则是bean中的名称
这样就完成了Bean与Bean的依赖关系