Spring 的自动装配 vs 手动注入

Spring 的自动装配(Autowiring)核心作用是减少手动配置依赖注入的代码量,让 Spring 容器自动识别并注入 Bean 之间的依赖关系,无需开发者在 XML 或注解中显式声明每一个依赖。下面我会通过「非自动装配(手动注入)」和「自动装配」的对比示例,清晰展示它是如何简化配置的。

一、先明确核心概念

自动装配的本质:Spring 容器根据指定的装配规则 (如按类型、按名称、按构造器等),自动为目标 Bean 注入其依赖的其他 Bean,无需手动通过 <property>(XML)或 @Autowired 显式指定(注:@Autowired 是触发自动装配的注解,本身是简化配置的核心)。

二、对比示例:手动注入 vs 自动装配

我们以一个简单的业务场景为例:UserService 依赖 UserDao,需要将 UserDao 注入到 UserService 中。

场景 1:XML 配置方式(最经典的对比)
1. 非自动装配(手动注入)

需要在 XML 中为 UserService 显式声明依赖的 UserDao,每一个依赖都要写 <property> 标签:

步骤 1:编写基础类

复制代码
// UserDao 实现类
public class UserDaoImpl implements UserDao {
    @Override
    public void query() {
        System.out.println("执行用户查询操作");
    }
}

// UserService 业务类(依赖 UserDao)
public class UserService {
    private UserDao userDao;

    // 必须提供 set 方法,供 XML 手动注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.query();
    }
}

步骤 2:XML 手动配置依赖

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">

    <!-- 定义 UserDao Bean -->
    <bean id="userDao" class="com.example.dao.UserDaoImpl"/>

    <!-- 定义 UserService Bean,手动注入 UserDao -->
    <bean id="userService" class="com.example.service.UserService">
        <!-- 显式声明依赖:每一个依赖都要写这个标签 -->
        <property name="userDao" ref="userDao"/>
    </bean>

</beans>
2. 自动装配(XML 方式)

只需在 <bean> 标签中添加 autowire 属性,Spring 会自动匹配依赖,无需写 <property>

基础类不变 (仍需保留 set 方法,因为默认按 byName/byType 装配需要 set 方法),XML 简化为:

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">

    <!-- 定义 UserDao Bean -->
    <bean id="userDao" class="com.example.dao.UserDaoImpl"/>

    <!-- 自动装配:autowire="byType" 按类型匹配依赖 -->
    <bean id="userService" class="com.example.service.UserService" autowire="byType"/>

</beans>

可以看到:省去了 <property> 标签 ,如果 UserService 有多个依赖(如 OrderDaoLogDao),手动注入需要写多个 <property>,而自动装配只需一个 autowire 属性即可,简化效果随依赖数量增加更明显。

场景 2:注解配置方式(实际开发中最常用)
1. 非自动装配(手动注入,几乎没人用)

即使使用注解,若不开启自动装配,仍需手动指定依赖(比如用 @Bean 手动注入):

复制代码
// 配置类
@Configuration
public class SpringConfig {

    // 定义 UserDao Bean
    @Bean
    public UserDao userDao() {
        return new UserDaoImpl();
    }

    // 手动注入 UserDao 到 UserService
    @Bean
    public UserService userService() {
        UserService userService = new UserService();
        // 手动调用 set 方法注入,每一个依赖都要写
        userService.setUserDao(userDao());
        return userService;
    }
}
2. 自动装配(注解方式,核心简化)

使用 @Autowired 注解触发自动装配,无需手动调用 set 方法或声明依赖:

复制代码
// 1. 开启组件扫描(让 Spring 识别 @Component 注解)
@Configuration
@ComponentScan("com.example")
public class SpringConfig {
    // 无需手动定义 Bean 和注入,全部由自动装配完成
}

// 2. UserDao 标注为组件
@Component
public class UserDaoImpl implements UserDao {
    @Override
    public void query() {
        System.out.println("执行用户查询操作");
    }
}

// 3. UserService 标注为组件,并自动装配 UserDao
@Component
public class UserService {
    // @Autowired 触发自动装配:Spring 自动找到 UserDao 类型的 Bean 注入
    @Autowired
    private UserDao userDao; // 甚至不需要 set 方法(Spring 通过反射直接注入字段)

    public void getUser() {
        userDao.query();
    }
}

简化效果:

  • 配置类中无需手动定义 Bean 和注入逻辑,只需开启组件扫描;
  • UserService 中无需写 set 方法,只需一个 @Autowired 注解,Spring 自动完成依赖注入;
  • UserService 依赖多个 Bean(如 UserDaoOrderDao),只需添加多个 @Autowired 注解,无需额外配置,手动注入则需要为每个依赖写注入代码。

三、自动装配的核心简化点总结

表格

配置方式 非自动装配(手动) 自动装配 简化效果
XML 配置 每个依赖都要写 <property> 标签 只需 autowire 属性,省去所有 <property> 减少 XML 标签数量,配置更简洁
注解配置 手动调用 set 方法 / 构造器注入 @Autowired 一键注入,无需手动操作 消除手动注入代码,代码更简洁
多依赖场景 依赖越多,配置 / 代码量线性增加 无论多少依赖,只需少量注解 / 配置 简化效果随依赖数量放大

四、自动装配的常用规则(补充)

Spring 自动装配支持 4 种规则(常用的是前两种):

  1. byType(按类型):最常用,Spring 查找与依赖类型匹配的 Bean 注入(若同类型有多个 Bean,需用 @Qualifier 指定名称);
  2. byName(按名称):查找与依赖属性名相同的 Bean 注入(如 userDao 属性匹配 id="userDao" 的 Bean);
  3. constructor(按构造器):通过构造器注入,匹配构造器参数类型的 Bean;
  4. no(默认):关闭自动装配,需手动注入。

总结

  1. Spring 自动装配的核心简化逻辑:将「开发者手动声明依赖注入关系」的工作,交给 Spring 容器根据规则自动完成,消除了大量重复的注入配置 / 代码;
  2. XML 中通过 autowire 属性省去 <property> 标签,注解中通过 @Autowired 省去手动调用 set / 构造器的注入代码;
  3. 依赖越多,自动装配的简化效果越明显,这也是实际开发中几乎全用自动装配的核心原因。
相关推荐
好学且牛逼的马2 小时前
Spring Boot 核心注解完全手册
java·spring boot·后端
彭于晏Yan2 小时前
Spring Boot监听Redis Key过期事件
java·spring boot·redis
weixin_418270532 小时前
window上codex 安装
java
低调小一2 小时前
OpenClaw 模型配置与火山 Coding Plan 支持清单(实践笔记)
java·前端·笔记·openclaw
xuxie992 小时前
Next 13 sqlite3 查找、网页
java·数据库·oracle
像少年啦飞驰点、2 小时前
Java策略模式从入门到实战:小白也能看懂的设计模式指南
java·设计模式·策略模式·编程入门·小白教程
꯭ 瞎꯭扯꯭蛋꯭2 小时前
3万字80道Java基础经典面试题总结
java·开发语言
程序员Terry2 小时前
别再用 if-else 堆砌代码了!策略模式让你的代码优雅十倍
java·设计模式
what丶k2 小时前
深入浅出责任链模式:解耦流程的优雅设计之道
java·责任链模式