1 IOC的概念与刨析
1.1 IOC简介
控制反转(Inversion of Control),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。
其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫依赖查找(Dependency Lookup)。
通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
通俗一点,解释如下:
控制反转,把对象的创建和对象之间调用的过程交给Spring进行管理;
使用IOC目的:为了降低耦合度。
1.2 IOC底层原理
所谓使用IOC的目的就是为了降低耦合度,在软件工程概论中我们知道,衡量一个软件设计好坏的标准,是 高耦合、低内聚。
因此,在刨析IOC底层原理的时候,我们不妨一步步来观察如何将代码之间耦合度慢慢降低
传统方式:
对象UserService依赖于对象User,即对象UserService在初始化或者运行到某一点的时候, 自己必须主动去创建对象User或者使用已经创建的对象User,控制权始终在自己手上。耦合度高! 两个对象关系过于紧密,当User的路径或者User中方法变了,UserService也会跟着变,所谓 牵一发而动全身 就是这个道理。
工厂模式:
通过一个UserFactory工厂,完成了对象的创建操作,降低了UserService和User之间的耦合度, 可是工厂和对象之间还是存在耦合度。 其实,完全消除耦合度是不可能的,只能降低耦合度。显然,工厂模式不是最优解。
引入IOC:
IOC底层原理涉及到xml解析、工厂模式与反射机制。IOC过程如下:
在xml配置文件中配置创建的对象;
<bean id="user" class="com.hxh.User"></bean> 1
假设还是有UserService与User类,想要在UserService类中调用User的方法,因此创建一个UserFactory工厂类,进行具体的操作,与上面讲解不同的是,这里不再直接返回一个对象,而是通过xml解析和反射的方式 做到进一步降低耦合度:
public class UserFactory { public static User getUser() throws ClassNotFoundException, InstantiationException, IllegalAccessException { //1.xml解析 //String classValue = class属性值; //2.通过反射创建对象 Class<?> clazz= Class.forName("com.hxh.User"); return (User) clazz.newInstance(); } }
此时,如果User的路径发生了更改,只需要更改xml文件中的配置,实现了耦合度进一步降低。
1.3 IOC容器
1.3.1 何为容器?
容器的核心是Bean,是豆荚的意思,我们的对象都被装在这个豆荚里统一管理。 可以理解成钞票是你的对象,而你需要把它存储在银行,让银行帮你打理,等你需要钱的时候,银行根据你的需要再把钱打给你… …(我可真是小财迷!)
而在xml里配置的
bean、@repository、 @service、@controller、@component
可以理解成抽象的 map (id-class),在项目启动的时候会读取配置文件里面的bean节点,根据全类名使用反射创建对象放到map里、扫描到打上上述注解的类也是通过反射创建对象放到map里。
此时,map中就放入了我们的对象,接下来我们在代码里需要用到里面的对象时,会通过依赖注入(DI)注入(autowired.resource等注解, xml里bean节点内的ref属性,项目启动的时候会读取xm|节点ref属性根据id注入,也会扫描这些注解,根据类型或id注入)。
1.3.2 IOC容器的理解
IOC思想基于IOC容器完成的,IOC容器的底层是对象工厂
还是再IOC底层原理举的例子,IOC容器会主动创建一个对象User注入到对象UserService需要的地方,从而让User和UserService失去了直接联系。 图示如下:
通过图可以看出来,全部对象的控制权全部上缴给"第三方"IOC容器,所以,IOC容器成了整个系统的关键核心,它起到了一种类似“粘合剂”的作用,把系统中的所有对象粘合在一起发挥作用, 如果没有这个"粘合剂",对象与对象之间会彼此失去联系。
Spring提供了IOC容器实现的两种方式(接口):
- BeanFactory: IOC基本容器的实现,是Spring内部的接口,不提供开发人员进行使用。加载配置文件的时候,不会创建对象,只有在使用的时候才去创建。
- ApplicationContext: BeanFactory接口的子接口,提供了更多更强的功能,一般由开发人员使用。加载配置文件的时候就会把配置文件对象进行创建。
2 IOC操作Bean管理
2.1 Bean管理
Bean管理指的是两个操作:
(1)Spring 创建对象;
(2)Spring 注入属性
Bean管理操作有两种方式
方式一:基于xml配置文件实现
方式二:基于注解的方式实现
2.2 Bean管理xml形式
2.2.1 创建对象与注入过程
一.创建对象
在spring配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象的创建。
<bean id="user" class="com.hxh.User"></bean> 1
在bean标签中,有许多常用的属性:
属性 | 含义 |
id | 获取对象的唯一标识 |
class | 类全路径 |
name | 与id基本相同,区别是name可以有特殊字符 |
创建对象,默认执行无参构造方法。
二.注入属性
与JavaSE一样,支持set注入和有参构造注入两种方式。
演示使用set方法进行属性的注入
1.首先创建一个类,类中含有对应的属性和set方法,以Book类为例!
public class Book { //创建属性 private String bname; //书名 private String bauthor; //作者 //对应的set public void setBname(String bname) { this.bname = bname; } public void setBauthor(String bauthor) { this.bauthor = bauthor; } //为了测试方便 public void testDemo(){ System.out.println(bauthor + "--" + bname); } }