实验一:组件(Bean)信息声明配置(IoC)
(无参、静态、非静态三种配置方法)
1. 准备项目
-
- 创建maven工程(spring-ioc-xml-01)
- 导入SpringIoC相关依赖 pom.xml
<dependencies>
<!--spring context依赖-->
<!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.6</version>
</dependency>
<!--junit5测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.1</version>
</dependency>
</dependencies>
创建spring的xml配置文件
2. 基于无参数构造函数
当通过构造函数方法创建一个 bean(组件对象) 时,所有普通类都可以由 Spring 使用并与之兼容。也就是说,正在开发的类不需要实现任何特定的接口或以特定的方式进行编码。只需指定 Bean 类信息就足够了。但是,默认情况下,我们需要一个默认(空)构造函数。
- 准备组件类,放在java中
package com.atguigu.ioc;
public class HappyComponent {
//默认包含无参数构造函数
public void doWork() {
System.out.println("HappyComponent.doWork");
}
}
2. xml配置文件编写 文件:resources/spring-bean-01.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">
<!-- 1.可以使用无参数构造函数实例化的逐渐,如何进行ioc配置
一个bean就是一个组件信息和逐渐对象
id 组件的标识要 唯一 方便后期读取
class 逐渐的类的权限定符
每次声明默认都是单例模式(每次都会实例化一次对象)下面那种就是实例化了两个
-->
<bean id="happyComponent1" class="com.atguigu.ioc_01.HappyComponent"/>
<bean id="happyComponent2" class="com.atguigu.ioc_01.HappyComponent"/>
</beans>
3. 基于静态工厂方法实例化
- 准备组件类
public class ClientService {
private static ClientService clientService = new ClientService();
private ClientService() {}
public static ClientService createInstance() {
return clientService;
}
}
2. xml配置文件编写 文件:resources/spring-bean-01.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">
<!-- 2.使用静态工厂类如何声明工厂方法进行ioc的配置
id 组件的标识
class 逐渐的类的权限定符
factory-method = "静态工厂方法"
每次声明默认都是单例模式(每次都会实例化一次对象)
-->
<bean id="clientService" class="com.atguigu.ioc_01.ClientService"
factory-method="createInstance"/>
</beans>
4. 基于实例工厂方法实例化
- 准备组建类
public class DefaultServiceLocator {
private static ClientServiceImplclientService = new ClientServiceImpl();
public ClientService createClientServiceInstance() {
return clientService;
}
}
2. xml配置文件编写 文件:resources/spring-bean-01.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">
<!-- 3.使用非静态工厂类如何声明工厂方法进行ioc的配置-->
<!-- 3.1 配置工厂类的组件信息 -->
<bean id="defaultServiceLocator" class="com.atguigu.ioc_01.DefaultServiceLocator"/>
<!-- 3.2 通过指定非静态工厂对象和方法名 来配置生成的ioc信息
factory-bean 指定的非静态工厂
factory-method 指定的非静态工厂的函数方法 -->
<bean id="clientService2"
factory-bean="defaultServiceLocator"
factory-method="createClientServiceInstance"/>
</beans>
实验二: 组件(Bean)依赖注入配置(DI)
<constructor-arg ref="userDao"/> <!-- 注入的参数是一个引用其他bean的 引用beanid值-->
<constructor-arg value="18"/> <!-- 注入的参数是一个直接的数值-->
1. 基于构造函数的依赖注入(单个构造参数)
<beans>
<!-- 单个构造参数的注入 -->
<!-- 引用类bean声明 -->
<bean id="userService" class="com.atguigu.ioc_02.UserService">
<!-- 构造函数引用 -->
<constructor-arg ref="userDao"/>
</bean>
<!-- 被引用类bean声明 (声明的顺序不重要)-->
<bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
</beans
2.基于构造函数的依赖注入(多构造参数解析)
<!-- 多个构造参数的注入 -->
<!-- 场景1: 多参数,可以按照相应构造函数的顺序注入数据 -->
<beans>
<bean id="userService" class="com.atguigu.ioc_02.UserService">
<!-- value直接注入基本类型值 -->
<constructor-arg value="18"/>
<constructor-arg value="赵伟风"/>
<constructor-arg ref="userDao"/>
</bean>
<!-- 被引用类bean声明 -->
<bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
</beans>
<!-- 场景2: 多参数,可以按照相应构造函数的名称注入数据 -->
<beans>
<bean id="userService" class="com.atguigu.ioc_02.UserService">
<!-- value直接注入基本类型值 -->
<constructor-arg name="name" value="赵伟风"/>
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="age" value="18"/>
</bean>
<!-- 被引用类bean声明 -->
<bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
</beans>
<!-- 场景3: 多参数,可以按照相应构造函数的角标注入数据
index从0开始 构造函数(0,1,2....)
-->
<beans>
<bean id="userService" class="com.atguigu.ioc_02.UserService">
<!-- value直接注入基本类型值 -->
<constructor-arg index="1" value="赵伟风"/>
<constructor-arg index="2" ref="userDao"/>
<constructor-arg index="0" value="18"/>
</bean>
<!-- 被引用类bean声明 -->
<bean id="userDao" class="com.atguigu.ioc_02.UserDao"/>
</beans>
3. 基于Setter方法依赖注入 (重点)
public Class MovieFinder{
}
public class SimpleMovieLister {
private MovieFinder movieFinder;
private String movieName;
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
public void setMovieName(String movieName){
this.movieName = movieName;
}
// business logic that actually uses the injected MovieFinder is omitted...
}
<beans>
<bean id="movieFinder" class="com.atguigu.ioc_02.MovieFinder"/>
<bean id="simpleMovieLister" class="com.atguigu.ioc_02.SimpleMovieLister">
<!-- (必填)name -> 属性名 调用set方法的名字 去掉set并首字母小写的值!
setMovieFinder -> movieFinder
(二选一) value | ref
-->
<property name="movieName" value="hello world"/>
<property name="movieFinder" ref="movieFinder"/>
</bean>
</beans>