声明式IOC
声明式IOC
一、简单使用
1.导入jar包
org.springframework.spring-context.5.2.9.RELEASE
org.springframework.spring-test.5.2.9.RELEASE
junit.4.13.1
2.配置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 id="AccountService" class="com.spring.two.service.AccountServiceImpl"></bean>
<bean id="AccountDao" class="com.spring.two.dao.AccountDaoImpl"></bean>
<!--构造函数方法注入依赖-->
<bean id="AccountService2" class="com.spring.two.service.AccountServiceImpl2">
<constructor-arg name="name" value="neo"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="birthday"></constructor-arg>
</bean>
<bean id="birthday" class="java.util.Date"></bean>
<!--set方法注入依赖-->
<bean id="AccountService2" class="com.spring.two.service.AccountServiceImpl2">
<property name="name" value="neo"></property>
<property name="age" value="17"></property>
<property name="birthday" ref="birthday"></property>
</bean>
<!--复杂类型的依赖注入-->
<bean id="AccountService3" class="com.spring.two.service.AccountServiceImpl3">
<!--注入数组:Integer[]-->
<property name="integer">
<array>
<value>1111</value>
<value>2222</value>
<value>3333</value>
</array>
</property>
<!--注入List:List<Double>-->
<property name="list">
<list>
<value>1.39</value>
<value>2.56</value>
<value>3.84</value>
</list>
</property>
<!--注入set:Set<String>-->
<property name="set">
<set>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</set>
</property>
<!--注入map:Map<Integer, String>-->
<property name="map">
<map>
<entry key="1" value="AAA"></entry>
<entry key="2" value="BBB"></entry>
<entry key="3" value="CCC"></entry>
</map>
</property>
<!--注入properties对象:prperties-->
<property name="properties">
<props>
<prop key="1">11</prop>
<prop key="2">22</prop>
<prop key="3">33</prop>
</props>
</property>
</bean>
</beans>
3.通过ApplicationContext对象加载配置文件,创建容器
ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
AccountService service=context.getBean("AccountService", AccountService.class);
service.insert();
二、IOC类结构
ApplicationContext接口:实现了BeanFactory、ResourceLoader等接口,定义了容器的实现规则,以及加载配置文件的规则。
ApplicationContext实现类:通过配置内容创建容器。
ClassPathXmlApplicationContext: 加载类路径下的配置文件,创建容器;
FileSystemXmlApplicationContext: 加载磁盘路径下的配置文件,创建容器;
AnnotationConfigApplicationContext: 读取注解,创建容器;
ApplicationContext接口 VS BeanFactory接口:
ApplicationContext:适用于单例对象
默认立即加载:ApplicationContext读取完配置文件之后,创建配置文件中的所有对象。对象被调用时,返回已创的对象。
可以通过配置文件,改变对象的创建模式(单例,多例)。
BeanFactory:适用于多例对象
延迟加载:当对象d被需要时,通过配置文件,创建对象。
三、<bean>标签
用于在配置文件中,定义容器对象
子标签:
<constructor-age>:通过构造方法,注入依赖
<property>:通过set方法,注入依赖
属性:
id:对象在容器中的唯一标识。
class:对象的全限定类名
scope:对象的作用范围。
init-method:初始化方法名
destroy-method:销毁方法名
scope属性:容器对象的作用范围。
a)singleton:默认的,创建单例对象。
生命周期:
出生:立即加载。容器一旦加载配置文件,对象就随之创建;
存活:只要容器存活,对象就存活;
死亡:容器销毁,对象也死亡。
d)prototype: 创建多例对象。
生命周期:
出生:对象被使用时,由Spring框架创建;
存活:对象使用过程中一直存活;
死亡:对象长时间不使用并没有别的对象引用时,由垃圾的回收期回收。
c)request: 作用于web应用的一次请求范围,将对象存储到request域中
d)session:作用于web应用的一次会话范围,将对象存储在session域中。
e)global-session:作用于集群环境的会话范围。
集群环境:同一IP的所有服务器中,一次会话中共享数据。如下图
通过bean标签创建对象的三种方式:
a)<bean id=””, class=””>: 使用类的默认构造函数创建对象,并存入Spring容器。
如果类中没有默认构造函数,则对象无法创建
b)<bean id=””, class=”全限定类名”, factory-method=”方法”>
使用工厂的方法创建对象(某个类的方法创建对象,并存入core contrainer)
c)<bean id=””, class=”全限定类名”, factory-mehtod=”方法”>
使用工厂的静态方法创建对象(某个类的静态方法创建对象,并存入spring容器)
四、依赖注入 Dependency Injection
Spring通过IOC以非OOP的方式创建对象,降低程序间的耦合。
并且Spring维护类之间的依赖关系,即当类需要使用其他类的对象时,由Spring提供所依赖的对象,我们只需要在配置文件中说明依赖的关系,这就称为依赖注入。
依赖注入的类型:
a)基本类型和String:String会转成需要的基本类型
b)Bean类型(在配置文件中或注解中配置过的Bean类)
c)复杂类型:数组、List、Set、Map、Properties等
依赖注入的方式:
1.构造函数+<constructor-org>子标签
a)在类中,依赖通过类构造函数的参数赋值。
b)在配置文件中,通过<constructor-org>标签注入依赖:
属性:type: 注入数据的类型
index:注入数据的索引
name: 注入数据的参数名
value:要注入的基本类型或String类型的数据。
ref:要注入的bean对象。包括注解配置的或xml配置的bean对象
<bean id="AccountService2" class="com.spring.two.service.AccountServiceImpl2">
<constructor-arg name="name" value="neo"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="birthday"></constructor-arg>
</bean>
<bean id="birthday" class="java.util.Date"></bean>
优点:Spring创建bean对象时,依赖都被注入,否则无法创建成功
缺点:改变了bean对象实例化的方式,所需依赖必须注入,即使是用不到时
2.set方法+<property>标签
a)在类中,依赖通过setXXX方法赋值
b)配置文件中,通过<property>标签注入依赖:
属性:
name: 注入数据的set方法名
value:注入的基本类型或String类型数据
ref:注入的bean类型数据。
<bean id="AccountService2" class="com.spring.two.service.AccountServiceImpl2">
<property name="name" value="neo"></property>
<property name="age" value="17"></property>
<property name="birthday" ref="birthday"></property>
</bean>
优点:创建对象时,没有明确的依赖限制,直接使用默认构造函数创建;
缺点:如果对象的某个依赖必须存在,通过set方式无法满足此要求。
3.复杂类型的注入:
数组:
<property name="integer">
<array>
<value>1111</value>
<value>2222</value>
<value>3333</value>
</array>
</property>
List:
<property name="list">
<list>
<value>1.39</value>
<value>2.56</value>
<value>3.84</value>
</list>
</property>
Set:
<property name="set">
<set>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</set>
</property>
Map:
<property name="map">
<map>
<entry key="1" value="AAA"></entry>
<entry key="2" value="BBB"></entry>
<entry key="3" value="CCC"></entry>
</map>
</property>
Properties:
<property name="properties">
<props>
<prop key="1">11</prop>
<prop key="2">22</prop>
<prop key="3">33</prop>
</props>
</property>