04-springIOC03-通过配置类实现IOC

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注解的重要特性

  1. Bean命名

    @Bean              // 默认Bean名:student(方法名)
    @Bean("stu")       // 指定Bean名:stu
    @Bean(name = "studentBean") // 指定Bean名:studentBean
    
  2. 初始化过程

    创建Address对象 → 设置loc属性 → 创建Student对象 → 
    依次调用setter方法注入属性 → 返回完整Student对象
    
  3. 单例模式

    @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);
}
posted on 2025-10-05 16:32  笨忠  阅读(8)  评论(0)    收藏  举报