Spring IOC 详解:基于 XML 配置与注解的依赖注入

Spring 框架是 Java 开发中最常用的框架之一,其核心思想之一是 IOC(Inversion of Control,控制反转)。IOC 的核心思想是将对象的创建和依赖关系的管理交给 Spring 容器来处理,从而降低代码的耦合度。本文将深入探讨 Spring IOC 的实现方式,重点讲解基于 XML 配置和基于注解的两种形式。

1. 什么是 IOC?

IOC(控制反转)是 Spring 框架的核心思想之一。传统的 Java 开发中,对象的创建和依赖关系的管理通常由开发者手动完成,这种方式会导致代码的耦合度较高。而 Spring 通过 IOC 容器来管理对象的创建和依赖关系,开发者只需要通过配置文件或注解来声明对象及其依赖关系,Spring 容器会自动完成对象的创建和依赖注入。

1.1 IOC 的优势

  • 降低耦合度:对象的创建和依赖关系由 Spring 容器管理,开发者不需要手动管理对象之间的依赖关系。

  • 提高代码的可维护性:通过配置文件或注解声明对象及其依赖关系,代码更加清晰和易于维护。

  • 便于测试:Spring 容器可以轻松地注入模拟对象,便于单元测试。

2. 基于 XML 配置的 IOC

基于 XML 配置的方式是 Spring 最早支持的 IOC 实现方式。通过在 XML 文件中配置 Bean 的定义和依赖关系,Spring 容器会根据配置文件创建对象并注入依赖。

2.1 配置 Bean

在 XML 配置文件中,使用 <bean> 标签来定义一个 Bean。每个 Bean 都有一个唯一的 idname,并通过 class 属性指定 Bean 的类型。

复制代码
<bean id="user" class="com.qcby.entity.User"/>

2.2 依赖注入

Spring 支持两种依赖注入方式:构造器注入Setter 注入

2.2.1 构造器注入

通过构造器注入,Spring 容器会在创建对象时调用指定的构造器,并传入相应的参数。

复制代码
<bean id="user" class="com.qcby.entity.User">
    <constructor-arg name="age" value="18"/>
    <constructor-arg name="name" value="张三"/>
    <constructor-arg name="animal" ref="animal"/>
</bean>

<bean id="animal" class="com.qcby.entity.Animal"/>
2.2.2 Setter 注入

通过 Setter 注入,Spring 容器会在创建对象后调用相应的 Setter 方法来注入依赖。

复制代码
<bean id="animal" class="com.qcby.entity.Animal">
    <property name="strs">
        <array>
            <value>张三</value>
            <value>李四</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>小白</value>
            <value>小绿</value>
        </list>
    </property>
    <property name="map">
        <map>
            <entry key="1" value="aa"/>
            <entry key="2" value="bb"/>
        </map>
    </property>
</bean>

2.3 测试基于 XML 配置的 IOC

通过 ApplicationContext 加载 XML 配置文件,Spring 容器会自动创建并管理 Bean。

复制代码
@Test
public void test1() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");
    User user = (User) ac.getBean("user");
    user.run();
}

3. 基于注解的 IOC

随着 Spring 的发展,基于注解的 IOC 配置方式逐渐成为主流。通过注解,开发者可以在代码中直接声明 Bean 及其依赖关系,减少了 XML 配置的复杂性。

3.1 常用注解

Spring 提供了以下常用注解来管理 Bean:

  • @Component:通用的 Bean 注解,用于标注普通的 Java 类。

  • @Controller:用于标注控制器类(通常用于 Spring MVC)。

  • @Service:用于标注服务层类。

  • @Repository:用于标注数据访问层类(DAO)。

3.2 使用注解配置 Bean

通过在类上添加 @Component 注解,Spring 容器会自动将该类注册为 Bean。

复制代码
@Component(value = "user")
public class User {
    public void run() {
        System.out.println("人跑的快");
    }
}

3.3 依赖注入

Spring 提供了以下注解来实现依赖注入:

  • @Autowired:按类型自动注入依赖。

  • @Qualifier:与 @Autowired 配合使用,按名称注入依赖。

  • @Value:注入普通类型的值(如字符串、整数等)。

复制代码
@Component(value = "animal")
public class Animal {
    @Value("大奔")
    private String name;

    @Autowired
    private User user;

    public void flay() {
        System.out.println("一些动物会飞");
    }
}

3.4 开启注解扫描

在 XML 配置文件中,使用 <context:component-scan> 标签开启注解扫描。

复制代码
<context:component-scan base-package="com.qcby.entity"/>

3.5 测试基于注解的 IOC

通过 ApplicationContext 加载配置文件,Spring 容器会自动扫描并创建注解标注的 Bean。

复制代码
@Test
public void a() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");
    Animal animal = (Animal) ac.getBean("animal");
    animal.flay();
}

4. 总结

Spring IOC 是 Spring 框架的核心特性之一,通过控制反转和依赖注入,Spring 极大地简化了 Java 开发中的对象管理和依赖关系处理。本文详细介绍了基于 XML 配置和基于注解的两种 IOC 实现方式,并提供了相应的代码示例。

  • 基于 XML 配置的 IOC:适合传统的 Spring 项目,配置灵活但较为繁琐。

  • 基于注解的 IOC:适合现代 Spring 项目,配置简洁且易于维护。

无论是基于 XML 还是注解,Spring IOC 都能有效地降低代码的耦合度,提高代码的可维护性和可测试性。希望本文能帮助你更好地理解和使用 Spring IOC。

java 复制代码
package com.qcby.entity;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Component(value = "animal")
public class Animal {

    private String [] strs;
    private List<String> list;
    private Map<String,String> map;

    @Override
    public String toString() {
        return "Animal{" +
                "strs=" + Arrays.toString(strs) +
                ", list=" + list +
                ", map=" + map +
                '}';
    }

    public String[] getStrs() {
        return strs;
    }

    public void setStrs(String[] strs) {
        this.strs = strs;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void flay(){
        System.out.println("一些动物会飞");
    }
}
java 复制代码
import com.qcby.entity.Animal;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ATest {
    @Test
    public void a(){
        ApplicationContext ac=new ClassPathXmlApplicationContext("Spring.xml");
        Animal animal=(Animal) ac.getBean("animal");
        animal.flay();
    }
}
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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--开启注解扫描 com.qcby所有的包中的所有的类-->
    <context:component-scan base-package="com.qcby.entity"/>



    <!--    IOC管理bean-->
<!--    id:类的唯一标识符,class:类的全路径名-->
<!--    <bean id="user" class="com.qcby.entity.User">-->
<!--        <constructor-arg name="age" value="18"/>-->
<!--        <constructor-arg name="name" value="20"/>-->
<!--        <constructor-arg name="animal" ref="animal"/>-->
<!--    </bean>-->
<!--    <bean id="animal" class="com.qcby.entity.Animal">-->
<!--        <property name="strs">-->
<!--            <array>-->
<!--                <value>张三</value>-->
<!--                <value>李四</value>-->
<!--                <value>王五</value>-->
<!--                <value>赵六</value>-->
<!--            </array>-->
<!--        </property>-->
<!--        <property name="list">-->
<!--            <list>-->
<!--                <value>小白</value>-->
<!--                <value>小绿</value>-->
<!--                <value>小红</value>-->
<!--            </list>-->
<!--        </property>-->
<!--        <property name="map">-->
<!--            <map>-->
<!--                <entry key="1" value="aa"/>-->
<!--                <entry key="2" value="bb"/>-->
<!--                <entry key="3" value="cc"/>-->
<!--            </map>-->
<!--        </property>-->
<!--    </bean>-->
</beans>

参考文献:

相关推荐:

相关推荐
宁渡AI大模型3 分钟前
河南宁渡科技有限公司|宁渡课堂 AI 全栈面试分享,AI 应用开发高频考点汇总
java·c++·人工智能·python·深度学习·神经网络·rag
代码什么用4 分钟前
JSON一文速通
java·json
Lyyaoo.7 分钟前
【二分查找】【中等】搜索二维矩阵/排序数组的第一位和最后位置/搜索旋转排序数组/旋转排序数组中的最小值
java·数据结构·算法
shengjk114 分钟前
AI会让程序员失业吗?200年前的手工织工已经给出了答案
后端
土司大王16 分钟前
LeetCode hot100——153.寻找旋转排序数组中的最小值:Java 二分模板与 O(log n) 分析
java·算法·leetcode
磐链科技25 分钟前
交易所开发中的合规与安全:KYC、AML、冷热钱包设计要点
java·区块链
盖伦发发28 分钟前
MySQL InnoDB事务完整教程|ACID、MVCC、隔离级别、事务控制
经验分享·后端·spring·软件工程
一条泥憨鱼35 分钟前
苍穹外卖【day09| 对订单的各种操作】
后端·苍穹外卖
码农飞哥36 分钟前
企业级RAG系统架构详解
java·人工智能·ai编程·rag·ai应用
Wang's Blog38 分钟前
Java框架快速入门: Spring Security+OAuth2之搭建授权服务器(依赖与表结构)
java·服务器·spring