Spring IOC基于Java配置类详解
一、IOC容器核心概念
1.1 什么是IOC(控制反转)
// 传统方式:手动创建对象,控制权在程序员手中
Student student = new Student();
student.setName("张三");
// IOC方式:控制权交给Spring容器
ApplicationContext context = new AnnotationConfigApplicationContext(StuConfig.class);
Student student = context.getBean("stu");
核心思想:将对象的创建、依赖注入、生命周期管理交给容器处理,实现解耦。
1.2 DI(依赖注入)
public class Student {
private Address address; // 依赖关系
// Spring容器负责注入Address对象
public void setAddress(Address address) {
this.address = address;
}
}
二、实体类详解
2.1 Student类分析
public class Student {
// 1. 属性定义
private Address address; // 对象类型属性
private Integer id; // 基本包装类型
private String name; // 字符串类型
private Integer age; // 数值类型
// 2. 默认构造方法 - Spring创建对象时调用
public Student() {
System.out.println("Student无参构造器被调用");
}
// 3. Setter方法 - Spring通过setter注入依赖
public void setAddress(Address address) {
System.out.println("setAddress方法被调用");
this.address = address;
}
// 4. Getter方法 - 获取属性值
public Address getAddress() {
return address;
}
// 5. toString方法 - 对象信息展示
@Override
public String toString() {
return "Student{" +
"address=" + address +
", id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.2 Address类分析
public class Address {
private String loc; // 地址信息
// 无参构造 - Spring默认使用
public Address() {
System.out.println("Address无参构造器被调用");
}
// 有参构造 - 可用于构造器注入
public Address(String loc) {
this.loc = loc;
}
// Setter/Getter方法
public void setLoc(String loc) {
this.loc = loc;
}
public String getLoc() {
return loc;
}
}
三、配置类深度解析
3.1 @Configuration注解
@Configuration // 标识这是一个Spring配置类
public class StuConfig {
// 配置类的作用:替代传统的applicationContext.xml文件
// Spring容器会扫描这个类中的所有@Bean方法
}
@Configuration的作用:
- 告诉Spring这是一个配置类
- 包含一个或多个@Bean方法
- 替代XML配置文件
3.2 @Bean注解详解
@Bean("stu") // 将方法返回值注册为Spring Bean
public Student student() {
// 1. 创建依赖对象
Address address = new Address();
address.setLoc("毕节");
// 2. 创建主对象
Student student = new Student();
// 3. 设置属性值 - 这就是依赖注入的过程
student.setId(1001); // 注入基本类型值
student.setAge(18); // 注入数值类型值
student.setName("刘备"); // 注入字符串值
student.setAddress(address); // 注入对象依赖
// 4. 返回完整对象
return student;
}
@Bean注解的重要特性:
-
Bean命名:
@Bean // 默认Bean名:student(方法名) @Bean("stu") // 指定Bean名:stu @Bean(name = "studentBean") // 指定Bean名:studentBean -
初始化过程:
创建Address对象 → 设置loc属性 → 创建Student对象 → 依次调用setter方法注入属性 → 返回完整Student对象 -
单例模式:
@Bean @Scope("singleton") // 默认单例,整个Spring容器中只有一个实例 public Student student() { return new Student(); } @Bean @Scope("prototype") // 原型模式,每次获取都创建新实例 public Student student() { return new Student(); }
四、测试类执行流程分析
4.1 容器初始化过程
public static void main(String[] args) {
// 1. 创建基于注解的Spring容器
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(StuConfig.class);
// 执行流程:
// Step1: 加载StuConfig配置类
// Step2: 扫描@Configuration注解
// Step3: 执行所有@Bean方法创建Bean实例
// Step4: 将Bean存入Spring容器
// 2. 从容器中获取Bean
Student student = (Student) applicationContext.getBean("stu");
// 3. 使用Bean
System.out.println(student);
}
4.2 详细执行时序
1. new AnnotationConfigApplicationContext(StuConfig.class)
↓
2. Spring扫描StuConfig类,发现@Configuration注解
↓
3. Spring找到@Bean("stu")方法,执行student()方法
↓
4. 执行new Address() → 调用Address无参构造器
↓
5. 执行address.setLoc("毕节")
↓
6. 执行new Student() → 调用Student无参构造器
↓
7. 依次执行student对象的setter方法注入属性
↓
8. 将完整的Student对象放入Spring容器,命名为"stu"
↓
9. applicationContext.getBean("stu")从容器获取对象
↓
10. 调用student.toString()方法输出结果
五、核心知识点总结
5.1 必须掌握的注解
| 注解 | 作用 | 使用场景 |
|---|---|---|
@Configuration |
标记配置类 | 替代XML配置文件 |
@Bean |
注册Bean到容器 | 在配置类中定义Bean |
5.2 关键类说明
| 类名 | 作用 | 重要方法 |
|---|---|---|
ApplicationContext |
Spring容器接口 | getBean() |
AnnotationConfigApplicationContext |
基于注解的容器 | 构造方法接收配置类 |
5.3 Bean创建流程
配置类 → @Bean方法 → 创建对象 → 属性注入 → 存入容器 → 获取使用
5.4 与传统XML配置对比
XML配置方式:
<bean id="stu" class="com.zhongge.entity.Student">
<property name="id" value="1001"/>
<property name="name" value="刘备"/>
<property name="age" value="18"/>
<property name="address" ref="address"/>
</bean>
<bean id="address" class="com.zhongge.entity.Address">
<property name="loc" value="毕节"/>
</bean>
Java配置类优势:
- 类型安全:编译时检查
- 功能强大:可在方法中使用Java逻辑
- 易于重构:IDE支持良好
- 简洁直观:代码即配置
六、扩展练习
6.1 尝试修改配置
@Bean("student2")
public Student createStudent() {
Address address = new Address();
address.setLoc("北京");
Student student = new Student();
student.setId(1002);
student.setAge(20);
student.setName("关羽");
student.setAddress(address);
return student;
}
6.2 测试多个Bean
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(StuConfig.class);
// 获取不同名称的Bean
Student stu1 = (Student) context.getBean("stu");
Student stu2 = (Student) context.getBean("student2");
System.out.println("stu1: " + stu1);
System.out.println("stu2: " + stu2);
}
浙公网安备 33010602011771号