聊聊Spring IOC
写在前面
无论是JAVA开发还是面试总是提到Spring 的IOC,它不是一个具体的技术,而是一种设计思想。本篇我们就来详细学习一下IOC。
第一个问题,什么是IOC?
IOC全称(Inversion of Control),翻译成中文就是我们说的控制反转,它的意思就是将对象创建交给外部的容器去创建,它能做到两件事情:
1.可以使对象的创建不用再程序中写死,实现松耦合
2.它可以把对象交给别人处理
那么就有人说了,对象的创建是复杂的,因为其有依赖关系,那么IOC是怎么处理对象间的依赖关系呢?这是就引入另一个思想,DI(dependency injection),就是我们常说的 依赖注入,它可以处理对象的依赖关系。
关于IOC思想,我们可以举生活中的例子来理解,比如淘宝就是一个巨大的IOC容器,商家的店铺相当于一个个对象,当客户需要卖货,淘宝将商家店铺按需求展示给客户(这其实就是注入),这样做的好处是,第一淘宝对店铺有集中的管理,容易管理,第二客户只有在买货时才找淘宝对应的店铺,客户和店铺无强依赖关系。
由上面的介绍,我们可以这样理解,IOC是一种思想,而DI更多的是指的是「控制反转」这个思想的实现方式,无需自行创建或管理它们的依赖关系,依赖关系将被「自动注入」到需要它们的对象当中去。
我们在编程中可以发现,对象之间的依赖关系,其实就是给对象上的属性赋值!因为对象上有其他对象的变量,因此存在了依赖关系。那么Spring是如何给对象的属性赋值呢?主要由以下几种方式:
1. 通过构造函数
使用构造函数,就是在applicationContext.xml配置文件 中使用ref指定依赖的关系就可以,示例代码如下:
<bean id="emp" class="Emp"></bean>
<bean id="user" class="User" >
<!--通过constructor这个节点来指定构造函数的参数类型、名称、第几个-->
<constructor-arg index="0" name="id" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" name="username" type="java.lang.String" ref="emp"></constructor-arg>
</bean>
2.通过set方法给属性注入值
Setter 方法注入的方式是目前 Spring 主流的注入方式,它可以利用 Java Bean 规范所定义的 Setter/Getter 方法来完成注入,可读性和灵活性都很高,它不需要使用声明式构造方法,而是使用 Setter 注入直接设置相关的值,例如在service层通过set方法来把userDao注入到UserService中,然后在applicationContext.xml配置文件:通过property节点来给属性赋值,引用类型使用ref,基本类型使用value。示例代码如下:
UserService:
public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
//看看有没有拿到userDao
System.out.println(userDao);
}
public void save() {
userDao.save();
}
}
applicationContext.xml:
引用类型:
<!--创建userDao对象-->
<bean id="userDao" class="UserDao"/>
<!--创建userService对象-->
<bean id="userService" class="UserService">
<property name="userDao" ref="userDao"/>
</bean>
基本类型
<bean id="userDao" class="org.springframework.beans.userDao">
<property name="id" value="1"/>
<property name="name" value="Java"/>
</bean>
3.自动装配
我们主要看下使用注解来实现自动装配,用到了注解@Autowired。示例代码如下:
@Component
public class UserService {
private UserDao userDao ;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}