Spring—IOC控制反转和依赖注入(xml方式)
-
IOC的概念:
- 控制反转,将创建对象的权力从代码中剥离出来,以其他形式体现,例如配置文件
- 使用反射和配置文件的形式创建对象,可以通过调整配置文件,灵活的切换实现类,不需要修改代码,也不需要重新编译,降低了层次跟层次之间的耦合度
-
环境的搭建:
-
在maven的配置文件中引入依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> </dependencies>
-
在resources文件夹下创建xml文件(这里叫bean.xml,名字自定义),并引入以下约束
<?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"> <!--把对象的创建交给spring来管理--> <!--id就是唯一标识 class就是要创建类的全限定类名--> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> </bean> <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl"></bean> </beans>
-
进行类的创建
/** * 模拟一个表现层,用于调用业务层 */ public class Client { /** * 获取spring的ioc核定容器,并根据id获取对象 * * ApplicationContext的三种常用实现类 * ClassPathXmlApplicationContext:可以加载类路径下的配置文件,要求配置文件必须在类路径中 * FileSystemXmlApplicationContext:可以加载磁盘任意路径下的配置文件(必须有访问权限) * AnnotationConfigApplicationContext:用于读取注解来创建配置文件的 * * 核心容器的两个接口引发的问题: * ApplicationContext:单例对象适用,更多使用此接口 * 它在构建核心容器时,创建对象采取的策略的采用立即加载的方式,只要一读取完配置文件马上就创建配置文件中配置的对象 * BeanFactory:多例对象适用 * 它在构建核心容器时,创建对象采取的策略的是采用延迟加载的方式,什么时候根据id获取对象了什么时候才创建对象 * @param args */ public static void main(String[] args) { //获取核心容器对象,参数指定配置文件的位置 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); /* 根据id获取bean对象()两种方式 * */ //方式1:强转成service层的对象 IAccountService as = (IAccountService) ac.getBean("accountService"); //方式2:传入service层类的字节码文件,就不用强转了 IAccountDao ad = ac.getBean("accountDao", IAccountDao.class); } }
-
-
spring对bean管理的细节
-
创建bean的三种方式
-
<!--方式1:使用默认构造函数创建 在spring文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。 采用的就是默认构造函数创建对象,如果类中没有默认的构造函数,则创建类失败 --> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> </bean>
-
<!--方式2:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器中) class就是该工厂的全限定类名,factory-bean就是第一行bean的id,factory-method时该工厂中的方法名 --> <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean> <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService()"> </bean>
-
<!--方式3:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器中) class就是该工厂的全限定类名,factory-method时该工厂中的方法名 --> <bean id="accountService" class="com.itheima.factory.StaticFactory" factory-method="getAccountService()"> </bean>
-
-
bean对象的作用范围
<!--bean标签的作用范围 bean标签的scope属性 作用:用于指定bean的作用范围 取值:常用的就是单例的和多例的 singleton:单例的(默认值) prototype:多例的 request:作用于web的请求范围 session:作用于web的会话范围 global-session:作用域集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session --> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" scope="singleton"> </bean>
-
bean对象的生命周期
<!--bean标签的生命周期 单例对象 出生:当容器创建时出生 活着:只要容器还在,对象就一直活着 死亡:容器销毁,对象销毁 总结:单例对象的生命周期和容器相同 多例对象 出生:当我们使用对象时,spring框架进行创建对象 活着:对象只要一直使用就活着 死亡:对象长时间不使用,且没有别的对象引用时,由java垃圾回收机制回收 -->
-
-
spring依赖注入(Dependency Injection)
-
概念:ioc为了降低程序之间的耦合(依赖关系),依赖关系之间的维护就称之为依赖注入
-
依赖注入的方式:(如果是经常变化的数据,并不适用于注入的方式)
<!-- 依赖注入: 能注入的数据:有三类 基本数据类型和String 其它bean类型(在配置文件中或注解配置的bean) 复杂类型/集合类型 注入的方式:有三种 使用构造函数 使用set方法 使用注解 -->
-
使用构造函数注入
<!--构造函数的注入: 使用的标签:constructor-arg 标签的位置:bean标签中 标签中的属性: type:用于指定要注入的数据的类型,该数据的类型也是构造函数中某个或某个参数的类型 index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值,索引从0开始 name:用于指定给构造函数中的指定名称赋值 =========================以上三个用于指定给构造函数中的哪个参数赋值=============================== value:用于提供基本类型和String类型的数据 ref:用于指定其它bean类型数据,它指的是在spring的ioc核心文件中出现的bean对象 优势:在获取没有空参构造的bean对象时,注入数据是必须的操作,否则对象无法创建成功 弊端:改变了bean的实力化方式,是我们如果用不到这些数据页必须提供(不能写null) --> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> <constructor-arg name="name" value="张三"></constructor-arg> <constructor-arg name="age" value="18"></constructor-arg> <constructor-arg name="birthday" ref="now"></constructor-arg> </bean> <!--使用spring配置Date的bean,获取当前时间--> <bean id="now" class="java.util.Date"></bean>
-
使用set方式注入
<!--set方式注入(比构造函数注入常用) 使用的标签:property 标签的位置:bean标签中 标签中的属性: name:用于指定注入时所调用的set的方法名称(去掉方法名的set并将首字母改为小写;如setName–>name) value:用于提供基本类型和String类型的数据 ref:用于指定其它bean类型数据,它指的是在spring的ioc核心文件中出现的bean对象 优势:创建对象时没有明确的限制,可以直接使用默认构造函数 弊端:如果有某个成员必须有值,则获取对象时有可能set方法没有执行 --> <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"> <property name="name" value="王五"></property> <property name="age" value="19"></property> <property name="birthday" ref="now"></property> </bean> <!--使用spring配置Date的bean,获取当前时间--> <bean id="now" class="java.util.Date"></bean>
-
-
注入集合数据
<!--复杂类型/集合类型的注入, 用于给List结构注入的标签 list array set 用于给map结构注入的标签 map props --> <bean id="accountService2" class="com.itheima.service.impl.AccountServiceImpl2"> <!--给数组类型注入--> <property name="myStrs"> <array> <value>AA</value> <value>BB</value> <value>CC</value> </array> </property> <!--给List类型注入--> <property name="myList"> <list> <value>AA</value> <value>BB</value> <value>CC</value> </list> </property> <!--给Set类型注入--> <property name="mySet"> <set> <value>AA</value> <value>BB</value> <value>CC</value> </set> </property> <!--给Map类型注入--> <property name="myMap"> <map> <entry key="testA" value="AA"></entry> <entry key="testB"> <value>BB</value> </entry> </map> </property> <!--给properties类型注入--> <property name="myPros"> <props> <prop key="testA"></prop> <prop key="testB"></prop> </props> </property> </bean>
-