IOC:inverse of control反转控制
负责创建对象,管理对象(通过依赖注入),配置对象,并且管理这些对象的生命周期。
以前对象的创建是由开发人员自己维护,包括依赖关系也是自己注入;使用了spring之后,对象的创建以及依赖关系可以由spring完成创建以及注入。反转控制就是反转了对象的创建方式,从我们自己创建反转给了程序。
控制反转技术促进了松耦合。当应用了IOC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
DI:dependency injection依赖注入
实现IOC思想需要DI支持。
注入方式:
- set方法注入;
- 构造方法注入;
- 字段注入
注入类型:
- 值类型注入;(8大基本数据类型)
- 引用类型注入;(将依赖对象注入)
ApplicationContext和BeanFactory
BeanFactory:
- 原始接口,针对原始接口的实现类,功能较为单一;
- 接口实现类的容器,特点是每次在获得对象时才会创建对象。
ApplicationContext:
- 每次容器启动时就会创建容器中配置的所有对象,提供了更多功能;
- 从类路径下加载配置文件:ClassPathXmlApplicationContext
- 从硬盘绝对路径下加载配置文件:FileSystemXmlApplicationContext("d:/xxx/yyy/xxx")
结论:web开发中,使用applicationContext,在资源匮乏的环境可以使用BeanFactory。
Spring配置详解
1.Bean元素
<!-- 将User对象交给spring容器管理 -->
<!-- Bean元素:使用该元素描述需要spring容器管理的对象
name属性:给被管理的对象起个名字,获得对象时根据该名称获得对象(可以重复,可以使用特殊字符)
class属性:被管理对象的完整类名
id属性:与name属性一模一样,名称不可重复,不能使用特殊字符
结论:尽量使用name属性.
-->
<bean id="" name="user" class="com.hellodake.bean.User"></bean>
Spring容器管理的对象,被IOC容器初始化,通过依赖注入配置并管理,这些beans通过在容器中配置的元数据被创建。比如利用applicationContext.xml文件中以<bean></beans>定义。
Spring框架定义的beans默认都是singleton单例的,在bean tag中有个属性,singleton,如果它被置为true,那么默认为单例,否则为prototype。
2.三种对象创建方式
- 空参构造
- 静态工厂
- 实例工厂(创建userFactory对象,方法不静态)
3.scope属性
是在bean元素上加的。
<bean id="" name="user" class="com.hellodake.bean.User" scope=""></bean>
取值有四种:
- singleton(默认值):单例对象,被标识为单例的对象在容器中只会存在一份实例。
- prototype:多例原型,被标识为多例的对象,每次再获得才会创建,每次创建都是新的对象。
- request:web环境下,对象与request生命周期一致
- session:web环境下,对象与session生命周期一致
大部分情况下,都是使用默认值,但是在与struts框架连起来的时候,每次请求都会创建一个action,spring管理着Action对象,每次struts提出请求都要去跟spring要一个Action对象,所以这时候就要把scope属性配置为prototype。所以在整合struts2时ActionBean必须配置为prototype的。
4.生命周期属性
配置一个方法作为生命周期初始化方法,spring会在对象创建之后立即调用;
配置一个方法作为生命周期的销毁方法,spring容器在关闭并销毁所有容器中的对象之前调用。
解释Spring框架中bean的生命周期
-
Spring容器 从XML 文件中读取bean的定义,并实例化bean。
-
Spring根据bean的定义填充所有的属性。
-
如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。
-
如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
-
如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
-
如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。
-
如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
-
如果bean实现了 DisposableBean,它将调用destroy()方法。
哪些是重要的bean生命周期方法? 你能重载它们吗?
有两个重要的bean 生命周期方法,第一个是setup , 它是在容器加载bean的时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。
The bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)
5.spring的分模块配置
<!-- 导入其他spring配置文件 -->
<import resource="com/hellodake/b_create/applicationContext.xml"/>
6.属性注入
- set方法注入
基本类型值注入和引用类型值注入
<!-- set方法注入: -->
<bean name="user" class="com.hellodake.bean.User">
<!-- 为name属性注入tom值 -->
<property name="name" value="tom"></property>
<property name="age" value="18"></property>
<!-- 为car属性注入下方配置的car对象 -->
<property name="car" ref="car"></property>
</bean>
<!-- 将car对象配置到容器中才能注入 -->
<bean name="car" class="com.hellodake.bean.Car">
<property name="name" value="兰博基尼"></property>
<property name="color" value="黄色"></property>
</bean>
- 构造函数注入
首先类里面要有构造函数,先去类生成一个带参构造函数。如果构造函数有多个,默认的话是按照第一个来构造,但是可以在配置文件中配置属性的时候,后面加index标签,index标签指的是该属性是构造函数中的第几个参数。还可以指定参数的类型,用type标签。三个属性就可以定位到任意构造函数。
name属性:构造函数的参数名
index属性:构造函数的参数索引
type属性:构造函数的参数类型
<!-- 构造函数注入 -->
<bean name="user2" class="com.hellodake.bean.User">
<constructor-arg name="name" value="jerry" index="" type=""></constructor-arg>
<constructor-arg name="car" ref="car"></constructor-arg>
</bean>
- p名称空间注入
导入p名称空间;
使用p:属性完成注入:值类型和对象类型;
- spel注入
spring expression language spring表达式语言
引用类型不支持spring el
7.复杂类型注入
比如集合类,数组。