- ==目的:==降低耦合度
- ==技术:==xml解析、工厂模式、反射
ioc容器的实现
- spring框架提供了两种实现方式(两个接口)
- BeanFactory接口
- ioc容器的基本实现,是spring框架内部使用的接口,一般不提供给开发人员使用
- 在加载xml配置文件时,不会创建xml中的bean对象,在获取对象(使用)bean时才创建对象
- ApplicationContext接口
- 是BeanFactory的子接口,提供更多更强大的功能,一般由开发人员使用
- 在加载xml配置文件时,就创建对象xml中的bean对象
- BeanFactory接口
- ApplicationContext接口的两个主要实现类
- FileSystemXmlApplicationContext类
从系统中的全路径去获取配置文件 - ClassPathXmlApplicationContext类
从项目的相对类路径(一般从src/
路径开始)去获取配置文件
- FileSystemXmlApplicationContext类
eg:
- 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">
<!-- 配置User对象创建 -->
<bean id="user" class="com.spring5.User"></bean>
</beans>
- 对象生成
//1.加载spring配置文件
//方法1:ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//方法2:BeanFactory context = new ClassPathXmlApplicationContext("bean.xml");
//方法3:ApplicationContext context = new FileSystemXmlApplicationContext("C:\\Users\\HUAWEI\\idea-workspace\\spring5_demo1\\src\\bean.xml");
//方法4:
BeanFactory context = new FileSystemXmlApplicationContext("C:\\Users\\HUAWEI\\idea-workspace\\spring5_demo1\\src\\bean.xml");
//2.获取配置文件的对象
User user = context.getBean("user", User.class);
xml中创建bean对象
- 属性:
- id:起的别名
- name:与id 属性作用相同(区别:可以输入特殊符号)
- class:类的相对路径
- 基于无参构造方法创建对象
注意
如果类中没有无参构造方法,则无法创建
<bean id="book" class="com.bean.Book"></bean>
xml中注入属性
- DI:依赖注入,注入属性(是ioc具体实现的操作)
- 基于set 方法注入属性
注意
如果类中没有创建set 方法,则无法注入
<bean id="book" class="com.bean.Book">
<property name="name" value="易筋经"></property>
<property name="author" value="达摩祖师"></property>
</bean>
p名称空间注入,简化set 注入
<!-- 1. 创建p名称空间 -->
<beans xmlns:p="http://www.springframework.org/schema/p">
<!-- 2. 注入 -->
<bean id="book" class="com.bean.Book" p:name="易筋经" p:author="达摩祖师"></bean>
</beans>
- 基于有参构造方法注入属性
如果类中没有创建有参构造方法,则无法注入
<bean id="book" class="com.bean.Book">
<constructor-arg name="name" value="易筋经"></constructor-arg>
<constructor-arg name="author" value="达摩祖师"></constructor-arg>
</bean>
注入空值和特殊符号
- null空值
<bean id="book" class="com.bean.Book">
<property name="name">
<null />
</property>
</bean>
- 属性值包含特殊符号
- 进行转义字符
- 把值写成CDATA格式
<bean id="book" class="com.bean.Book">
<property name="author">
<value><![CDATA[%达摩祖师%]]></value>
</property></bean>
注入外部bean对象(ref)
- 需求
- 有两个类一个Service类和一个实现Dao接口DaoImpl类
- 需要在Service类的对象中调用Dao类向上转型对象中的方法
- 前提条件
- Service类中有Dao接口对象的属性
private UserDao userDao;
- 有set方法设置Dao接口对象
public void setUserDao(UserDao userDao){this.userDao = userDao;}
- xml配置
<!--外部bean -->
<bean id="userDaoImpl" class="com.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.service.UserService">
<!--
1. name:属性名称
2. ref:是外部bean的别名
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
注入内部Bean对象和级联赋值
- 需求
一个员工Emp类中的dept(部门)属性是一个对象
- xml配置
基于set方法注入属性
<bean id="emp" class="com.bean.Emp">
<!-- 设置普通属性 -->
<property name="name" value="lucy"></property>
<property name="gender" value="女"></property>
<!-- 设置对象属性 -->
<property name="dept">
<bean id="dept" class="com.bean.Dept">
<property name="name" value="保安部"></property>
</bean>
</property>
</bean>
- 级联赋值
基于set和get方法注入属性- 方法1
<bean id="emp" class="com.bean.Emp">
<!-- 设置普通属性 -->
<property name="name" value="lucy"></property>
<property name="gender" value="女"></property>
<!-- 设置对象属性 -->
<property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.bean.Dept">
<property name="name" value="保安部"></property>
</bean>
- 方法2
<bean id="emp" class="com.bean.Emp">
<!-- 设置普通属性 -->
<property name="name" value="lucy"></property>
<property name="gender" value="女"></property>
<!-- 设置对象属性 -->
<property name="dept.name" value="保安部"></property>
</bean>
<bean id="dept" class="com.bean.Dept">
<property name="name" value="财务部"></property>
</bean>
注入集合类型属性
基于set方法注入属性
- 数组类型
<bean id="stu" class="com.bean.Stu">
<property name="courses">
<array>
<value>Java</value>
<value>C++</value>
<value>Python</value>
</array>
</property>
</bean>
- List类型
<bean id="stu" class="com.bean.Stu">
<property name="courses">
<list>
<value>Java</value>
<value>C++</value>
<value>Python</value>
</list>
</property>
</bean>
- Map类型
<bean id="stu" class="com.bean.Stu">
<property name="courses">
<map>
<entry key="c001" value="Java"></entry>
<entry key="c002" value="C++"></entry>
<entry key="c003" value="Python"></entry>
</map>
</property>
</bean>
- Set类型
<bean id="stu" class="com.bean.Stu">
<property name="courses">
<set>
<value>Java</value>
<value>C++</value>
<value>Python</value>
</set>
</property>
</bean>
注入对象集合类型属性
基于set方法注入属性
- 需求
private List<Course> sourses;
- xml配置
<!-- 注入的对象 -->
<bean id="course1" class="com.bean.Course">
<property name="name" value="Java"></property>
</bean>
<bean id="course2" class="com.bean.Course">
<property name="name" value="C++"></property>
</bean>
<!-- Student类 -->
<bean id="stu" class="com.bean.Stu">
<property name="courses">
<list>
<!-- ref:填写bean的id值 -->
<ref bean="course1"></ref>
<ref bean="course2"></ref>
</list>
</property>
</bean>
提取集合类型注入属性
基于set方法
- List类型(其他集合类型类似)
<!-- 1. 配置beans属性, 添加util -->
<beans xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 2. 创建List集合对象 -->
<util:list id="courseList">
<!-- 普通类型 -->
<value>Java</value>
<value>C++</value>
<!-- 对象类型 -->
<ref></ref>
</util:list>
<!-- 3. 注入属性 -->
<bean id="stu" class="com.bean.Stu">
<property name="courses" ref="courseList"></property>
</bean>
</beans>