二、Ioc(控制反转)
文章目录
1、Ioc的定义
Ioc(inversion of Control),即”控制反转“,它是一种设计思想,即把创建对象的控制权交给工厂,工厂负责创建新的对象并返回。
原始的获取对象方式:采用new的方式,主动获取
**控住反转后:**获取对象时,只需要跟工厂要,工厂为我们查找或者创建对象,是被动的
2、配置文件bean.xml
其功能是配置托管给Spring的对象,
2.1bean标签包含的属性
- id:指定对象在容器中的标识,将其作为参数传入getBean()方法可以获取对应的对象。
- class:全限定类名,默认情况下调用类的无参构造器。
- scope:对象的作用范围。
- singleton:单例对象,默认值
- prototype:多例对象
- request:将对象存入到web项目的request域中
- seesion:将对象存入到web项目集群的session域中,若不存在集群,则global session相当于seesion
- init-method:指定类中的初始化方法名称,在对象创建成功之后执行。
- destory-method:指定类的销毁方法名称,对prototype多例对象没有作用,因为多例对象的销毁时机不收容器的控制。
2.2 创建bean对象的三种方式
- 使用默认无参数构造器创建对象,默认情况下会根据默认的无参构造函数来创建对象,若Bean类中没有默认的无参构造函数,则会创建失败
<bean id="accountService" class="com.simon.service.impl.AccountService"></bean>
-
采用工厂方法
创建工厂
public class Factory { public IAccountService getAccountService(){ return new AccountService();//返回的是AccountService的对象 }
使用bean工厂构造对象
<bean id="factoryInstance" class="com.simon.factory.Factory"></bean> <bean id="accountService" factory-bean="factoryInstance" factory-method="getAccountService"></bean>
其中factory-bean是bean工厂对象的唯一标识符,factory-method是bean工厂里构造AccountService对象的方法
-
采用静态工厂方法
创建静态工厂
public class Factory { public static IAccountService getAccountService(){ return new AccountService();//返回的是AccountService的对象 }
使用bean工厂构造对象
<bean id="accountService" class="com.simon.factory.Factory" factory-method="getAccountService"></bean>
2.2bean的生命周期
2.3 bean对象的获取
-
1、获取核心容器对象
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
ApplicationContext有三个主要的实现类可以获取容器对象
- ClassPathXmlApplicationContext:它可以加载类路径下的配置文件
- FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
- AnnotationCobnfigApplicationContext:
同样的,实现核心容器有两个接口
- ApplicationContext:它在构建核心容器时,创建对象采取的策略是立即加载的方式,即读完配置文件后就会马上创建配置的对象,适用于单例对象
- BeanFactory:它在构建核心容器时是采用延迟加载的方式,即什么时候根据id创建对象了,什么时候才真正的创建对象,适用于多例对象。
2.4bean的生命周期
- 单例对象:一个应用只有一个对象实例,它的作用范围就是整个应用
对象出生:当应用加载,创建容器时,对象就会被创建
对象存活:只用容器在,对象就会一直活着
对象死亡:当应用卸载,销毁容器时,对象就会被销毁
- 多例对象:每次访问对象,就会创建新的实例
对象出生:当使用对象时,就会创建出新的实例
对象存活:只要对象在使用中,就会一直存活
对象死亡:当对象长时间不被使用,就会被java的垃圾回收器回收。
3、依赖注入(Dependency Injection)
IOC的作用是降低程序间的耦合(依赖关系),使得依关系的管理交给Spring,即在当前类需要用到其它类的对象,都由Spring为我们提供,我们只需在配置文件中说明即可,在Spring中对依赖关系的维护称为依赖注入。
可以依赖注入的数据类型
- 基本数据类型和String
- 其它bean类型(在配置文件中或注解配置过的bean)
- 复杂类型/集合类型
注入的方式
- 构造函数
- set方法
- 注解
3.1使用构造函数注入
使用constructor-arg标签,放置在bean的内部
标签的属性:
- type:用于指定要注入的数据类型,该数据类型也是构造函数中某个或某些参数的类型。
- index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引位置从0开始。
- name:用于指定给构造函数中指定名称的参数赋值
以上三个君是用于指定给构造函数中那个参数赋值
- value:用于提供基本类型和String类型
- ref:用于指定其它的bean类型数据,它指的是在Spring的Ioc核心容器中出现过的bean对象。
优势:在获取bean对象时,注入数据时必须的操作,否则无法成功。
劣势:改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须得提供。
AccountService类
public class AccountService implements IAccountService {
private String name;
private Integer age;
private Date birthday;
public AccountService(String name, Integer age, Date birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}
public void saveAccount() {
System.out.println("AccountService存取money"+name+","+age+","+birthday );
}
}
采用构造函数注入
<bean id="accountService" class="com.simon.service.impl.AccountService">
<constructor-arg name="age" value="24"></constructor-arg>
<constructor-arg name="name" value="Simon"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<bean id="now" class="java.util.Date"></bean>
3.2使用set方法注入
在bean的标签内部使用标签property
标签的属性
- name :用于指定注入时所调用的set方法和名称
- value:用于提供基本类型和String类型的数据
- ref:用于指定其它bean类型的数据。它指的是在Spring的Ioc核心容器中出现过的bean对象
优势:创建对象时没有明确的限制,可以直接使用默认构造函数
劣势:如果某个成员必须有值,则set方法无法保证一定注入
AccountService类
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
采用set方法注入
<bean id="now" class="java.util.Date"></bean>
<bean id="accountService" class="com.simon.service.impl.AccountService">
<property name="age" value="25"></property>
<property name="name" value="SimonLang"></property>
<property name="birthday" ref="now"></property>
</bean>
3.3注入集合数据类型
用于给List结构集合注入的标签:list、array、set
用于给map结构集合注入的标签:map、properties
AccountService类
private String[] myStrs;
private List<String> mylist;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myProps;
<bean id="accountService" class="com.simon.service.impl.AccountService">
<property name="myStrs">
<array>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</array>
</property>
<property name="mylist">
<list>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</list>
</property>
<property name="mySet">
<set>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</set>
</property>
<property name="myMap">
<map>
<entry key="Simon" value="郎"></entry>
<entry key="Snow" value="坤"></entry>
<entry key="LUCY" value="坤"></entry>
</map>
</property>
<property name="myProps">
<props>
<prop key="Simon">坤</prop>
<prop key="Snow">郎</prop>
</props>
</property>
</bean>