Spring5 – 学习笔记 - 3.IoC容器
1、IoC底层原理。
(1)什么是IoC。
控制反转,把对象创建和对象直接的调用过程,交给Spring管理。
使用IoC的目的,为了降低耦合度。
上一篇的入门案例就是IoC的基本实现。
(2)IoC底层原理。
xml注解、工厂模式、反射。
2、IoC接口(BeanFactory)
(1)IoC思想基于IoC容器完成,IoC容器底层就是对象工厂。
(2)Spring提供IoC容器实现的两种方式:(两个接口)。
BeanFactory:
IoC容器基本实现,是Spring内部的使用接口,一般不提供开发人员使用,
*加载配置文件时,不会创建对象,在获取(使用)对象时才去创建对象。
ApplicationContext:
是BeanFactory的子接口,提供更多更强大的功能,一般由开发人员进行使用,
*加载配置文件时,就会创建把配件文件对象进行创建。
两个接口功能相似,都可以加载配置文件,创建对象。第二个接口在服务器启动时就会把对象也进行创建,可以进行节约时间,因为服务器一般只启动一次,后续就不需要启动了。
(3)ApplicationContext接口的实现类。
FileSystemXmlApplicationContext:
参数需要写配置文件在系统盘的位置,也就是需要带盘符路径。
ClassPathXmlApplicationContext:
参数是类路径。
3、IoC操作Bean管理
(1)什么是Bean管理。
Bean管理指的是两个操作即:
Spring创建对象,注入属性。
(2)Bean管理操作有两种方式。
基于xml配置文件方式实现,基于注解方式实现。
4、IoC操作Bean管理(基于xml)
(1)创建对象:
在Spring配置文件中使用bean标签,在标签中添加对应属性,就实现创建对象。
<!--配置user类对象创建-->
<bean id="user1" class="com.yh.spring5.User"></bean>
在bean标签中有很多属性,俩个常用属性:
*id属性:唯一标识。
*class属性:类全路径。
创建对象时,默认执行无参构造方法,完成对象创建。
(2)注入属性:
DI:依赖注入,也就是注入属性。要在创建对象的基础上完成,要先创建对象。
4.2.1.使用set方法进行注入。
创建类,定义属性和对应的set方法。
/**
* 使用set方法进行属性注入
*/
public class User {
//创建属性
private String userName;
private int userAge;
//创建属性对应的set方法
public void setUserName(String userName){
this.userName=userName;
}
public void setAge(int userAge){
this.userAge=userAge;
}
}
在Spring配置文件中配置对象的创建、属性的注入。
<!--1.配置user类对象创建-->
<!--2.set方法进行属性注入-->
<bean id="user1" class="com.yh.spring5.User">
<!--使用property完成属性的注入
name:类中的属性名
value:向属性输入的值
-->
<property name="userName" value="张1"></property>
<property name="userAge" value="20"></property>
</bean>
4.2.2.使用有参构造进行注入
创建类,定义属性,定义属性对应有参构造方法。
public class Book {
//属性
private String bookName;
private String bookAuthor;
//有参构造方法
public Book(String bookName,String bookAuthor){
this.bookName=bookName;
this.bookAuthor=bookAuthor;
}
}
在Spring配置文件中进行配置,有参构造方法进行注入属性。
<!--1.配置book类对象创建-->
<!--2.使用有参构造方法注入属性-->
<bean name="book1" class="com.yh.spring5.Book">
<!--constructor-arg 标签 还有index(索引)属性和name效果一样,第一个参数的值就是0依次增加
一般使用名称name属性
-->
<constructor-arg index="0" value="红楼梦"></constructor-arg>
<constructor-arg name="bookAuthor" value="曹雪芹"></constructor-arg>
</bean>
4.2.3.P名称空间注入(set注入的一种)
创建类,定义属性和对应的set方法。
/**
* 使用set方法进行属性注入
*/
public class User {
//创建属性
private String userName;
private int userAge;
//创建属性对应的set方法
public void setUserName(String userName){
this.userName=userName;
}
public void setAge(int userAge){
this.userAge=userAge;
}
}
在配置文件中添加P名称空间。
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
在Spring配置文件中进行配置,P名称空间方法进行注入属性。
<!--1.配置user类对象创建-->
<!--2.p名称空间方法进行属性注入-->
<bean name="user2" class="com.yh.spring5.User" p:userName="张二" p:userAge="22"></bean>
4.2.4.赋予属性Null值、属性值中有特殊符号
Null值,在Spring配置文件中进行配置。
<!--1.配置user类对象创建-->
<!--2.set方法进行属性注入-->
<bean id="user3" class="com.yh.spring5.User">
<property name="userName" value="张san"></property>
<property name="userAge" value="26"></property>
<!--给属性设置null值-->
<property name="userAddress">
<null/>
</property>
</bean>
特殊符号,在Spring配置文件中进行配置。
id="user4" class="com.yh.spring5.User">
<property name="userName" value="张4"></property>
<property name="userAge" value="29"></property>
<!--属性中有特殊符号-->
<property name="userAddress">
<!--
1.转义字符 比如<>的转义字符为<>
2.CDATA 格式为:<![CDATA[值]]> CDATA中的值就会被原样输出
-->
<value><112> <![CDATA[<221>]]></value>
</property>
</bean>
4.2.5.注入属性-外部Bean
Dao接口。
public interface UserDao {
void add();
}
DaoImpl实现类。
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("UserDaoAdd....");
}
}
Service类。
public class UserService {
private UserDao userDao;
public void setUserDao(UserDaoImpl userDao){
this.userDao=userDao;
}
public void add(){
System.out.println("UserServiceAdd............");
userDao.add();
}
}
在Spring配置文件中进行配置。
<!--创建dao和service对象-->
<bean id="userDaoImpl" class="com.yh.spring5.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.yh.spring5.service.UserService">
<!--注入userdao对象
name属性:值为属性的名称
ref属性:xml文件中dao对象的id值
-->
<property name="userDao" ref="userDaoImpl"></property>
</bean>
进行测试。
@Test
public void tt1() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
UserService userService=context.getBean("userService", UserService.class);
userService.add();
}
测试结果。
4.2.6.内部Bean方式,在Spring配置文件中进行配置。
<!--内部Bean方式进行注入属性-->
<bean name="userService2" class="com.yh.spring5.service.UserService">
<!--
对象类型属性定义
property标签的name属性值是类中的成员名称
-->
<property name="userDao">
<bean name="userDaoImpl" class="com.yh.spring5.dao.UserDaoImpl"></bean>
</property>
</bean>
进行测试。
//测试使用内部Bean注入
@Test
public void t1(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean2.xml");
UserService userService=context.getBean("userService2",UserService.class);
userService.add();
}
测试结果。
4.2.7.级联赋值1。
员工类。
//员工类
public class Staff {
private String sname;
private String gender;
//代表这个员工属于哪个部门
private Department department;
public void setSname(String sname){
this.sname=sname;
}
public void setGender(String gender){
this.gender=gender;
}
public void setDepartment(Department department){
this.department=department;
}
public Department getDepartment(){
return this.department;
}
public void print(){
System.out.println(sname+" , "+gender+" ,"+department);
}
}
部门类。
//部门类
public class Department {
private String dname;
public void setDname(String dname){
this.dname=dname;
}
@Override
public String toString() {
return "Department{" +
"dname='" + dname + '\'' +
'}';
}
}
级联赋值1,在Spring配置文件中进行配置。
<!--级联赋值1-->
<bean name="staff1" class="com.yh.spring5.bean.Staff">
<!--正常属性-->
<property name="sname" value="zhangsan"></property>
<property name="gender" value="男"></property>
<!--对象属性-->
<property name="department">
<bean name="department1" class="com.yh.spring5.bean.Department">
<property name="dname" value="安保部"></property>
</bean>
</property>
</bean>
测试。
//测试级联赋值1
@Test
public void t3(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean3.xml");
Staff staff=context.getBean("staff1", Staff.class);
staff.print();
}
测试结果。
4.2.8.级联赋值2。
级联赋值2,在Spring配置文件中进行配置。
<!--级联赋值2-->
<bean name="staff2" class="com.yh.spring5.bean.Staff">
<!--正常属性-->
<property name="sname" value="张三"></property>
<property name="gender" value="nan"></property>
<!--对象属性-->
<property name="department" ref="department2"></property>
<!--这个方式还需要生成对象属性的get方法-->
<property name="department.dname" value="技术部"></property>
</bean>
<bean name="department2" class="com.yh.spring5.bean.Department"></bean>
测试。
//测试级联赋值2
@Test
public void t4(){
ApplicationContext context=new ClassPathXmlApplicationContext("bean3.xml");
Staff staff=context.getBean("staff2",Staff.class);
staff.print();
}
测试结果。