在上文《用最简单的方式理解 IOC 思想》中,对IOC思想有了认识,一句话总结IOC:
IOC,控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。
IOC 是 Spring 框架的核心内容,现在来看看IOC思想在 Spring 中的应用。
Spring IOC流程
Spring容器在初始化时,先读取配置文件,根据配置文件或元数据进一步创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。
Spring IOC实现方法
在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection,DI)。
Spring中使用多种方式完美的应用了IOC,可以使用 XML 配置,也可以使用注解配置,新版本的Spring可以零配置实现IOC。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
XML配置Bean
在项目中,一般我们创建一个beans.xml文件用来配置我们需要注入的Bean。
<?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"> <!--bean就是java对象 , 由Spring创建和管理--> <bean id="cat" class="com.hwl.pojo.Cat"> <property name="name" value="kiki"/> </bean> </beans>
获取注入的对象:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//getBean : 参数即为spring配置文件中bean的id . Cat cat = (Cat) context.getBean("cat");
这个过程中我们并没有 new Cat对象,但是我们可以用 context.getBean 获取到的cat调出并取得name属性值kiki。
这个对象哪来的?就是Spring创建的。
name属性怎么赋值到了这个对象上?也是Spring管理的。
这个过程就是通过XML配置Bean的方式实现了控制反转。
这个过程中很好的解释了控制反转这个词儿:
控制:Spring创建对象,而不是传统的那种在程序里面new一个对象。
反转:程序本身不创建对象,而是被动的接收对象。
在往深层一点理解,这个注入过程是怎么实现的?用set方法,思想就是上一篇中我们的简单例子那种思想,可以通过newClassPathXmlApplicationContext去浏览一下底层源码。
使用XML配置在一个对象里注入另一个对象,例如我们上篇中的例子,在这里使用XML来实现在service层类中注入dao层类:
<bean id="MysqlImpl" class="com.hwl.dao.impl.UserDaoMySqlImpl"/> <bean id="OracleImpl" class="com.hwl.dao.impl.UserDaoOracleImpl"/> <bean id="ServiceImpl" class="com.hwl.service.impl.UserServiceImpl"> <!--注意: 这里的name并不是属性 , 而是set方法后面的那部分 , 首字母小写--> <!--引用另外一个bean , 不是用value 而是用 ref--> <property name="userDao" ref="OracleImpl"/> </bean>
现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !
IOC创建对象的方式
上面我们已经知道,Spring IOC容器会创建对象,那它是怎么创建的呢?我们可以大胆猜想,容器虽然帮我们管理了,单归根到底也只是帮我们做了一些事情,创建一个对象底层还是和构造方法有关系的吧?没错~
- 通过无参构造方法创建
- 通过有参构造方法创建
这个验证其实很简单,在我们的POJO中的构造方法添加输出就可以看到了。
通过验证测试,我们发现:在配置文件加载的时候,被管理的对象都已经初始化了!
Spring 配置
Bean 配置
<!--bean就是java对象,由Spring创建和管理--> <!-- 1.id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符,如果配置id,又配置了name,那么name是别名,
2.name可以设置多个别名,可以用逗号,分号,空格隔开 如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
3.class是bean的全限定名=包名+类名 -->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"/> </bean>
import 导入
有时候合作开发中分成了几个beans.xml,需要汇总的时候就可以使用import
<import resource="{path}/beans.xml"/>
alias 别名
alias 用于为bean设置别名 , 而且可以设置多个别名。
<!--设置别名:在获取Bean的时候可以使用别名获取--> <alias name="user" alias="comUser"/>