Spring Bean 依赖注入

在 Spring 中,自动化装配和显式 Java 配置装配是两种核心方式。下面分别说明。


一、自动化装配

自动化装配包含两个步骤:

  1. 组件扫描:Spring 自动发现上下文中的 Bean

  2. 自动装配:Spring 自动满足 Bean 之间的依赖

1. 创建可被发现的 Bean

使用 @Component 注解标记一个类:

java 复制代码
@Component
public class UserService {
    public void save() {
        System.out.println("保存用户");
    }
}

2. 开启组件扫描

Java 配置类

java 复制代码
@Configuration
@ComponentScan(basePackages = "com.example.service")
public class AppConfig {
}

Spring Boot 自动扫描(在主类上)

java 复制代码
@SpringBootApplication  // 内含 @ComponentScan
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3. 自动装配依赖

使用 @Autowired

java 复制代码
@Component
public class UserController {
    @Autowired
    private UserService userService;

    public void handle() {
        userService.save();
    }
}

也可以用在构造器(推荐,方便单元测试):

java 复制代码
@Component
public class UserController {
    private final UserService userService;

    @Autowired  // 只有一个构造器时可省略
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

4. 处理歧义性

当多个 Bean 实现同一接口时,用 @Primary@Qualifier

java 复制代码
@Component
@Primary  // 优先使用
public class DataSourceA implements DataSource {}

@Component
@Qualifier("dataSourceB")
public class DataSourceB implements DataSource {}

使用处指定:

java 复制代码
@Autowired
@Qualifier("dataSourceB")
private DataSource dataSource;

二、通过 Java 代码装配 Bean(显式配置)

适合:第三方类库、无法加注解的类、需要复杂初始化逻辑的 Bean。

1. 基本用法

java 复制代码
@Configuration
public class AppConfig {

    @Bean
    public UserService userService() {
        return new UserService();
    }
}

@Bean 告诉 Spring:该方法返回一个对象,应注册为 Spring 应用上下文中的 Bean。

2. 注入依赖

方式一:方法调用(简洁)

java 复制代码
@Bean
public UserController userController() {
    return new UserController(userService());
}

方式二:方法参数注入(推荐,更灵活)

java 复制代码
@Bean
public UserController userController(UserService userService) {
    return new UserController(userService);
}

Spring 会自动从上下文中找到 UserService 类型的 Bean 传入。

3. 复杂初始化示例

java 复制代码
@Bean
public DataSource dataSource() {
    HikariConfig config = new HikariConfig();
    config.setJdbcUrl("jdbc:mysql://localhost:3306/test");
    config.setUsername("root");
    config.setPassword("123456");
    return new HikariDataSource(config);
}

4. 混合使用

Java 配置中可以引用通过 @Component 扫描得到的 Bean:

java 复制代码
@Configuration
@ComponentScan("com.example.service")
public class AppConfig {

    @Bean
    public ReportService reportService(UserService userService) {
        // userService 来自组件扫描
        return new ReportService(userService);
    }
}

三、对比总结

特性 自动化装配 (@Component + @Autowired) Java 显式配置 (@Configuration + @Bean)
适用场景 自己编写的类 第三方类、复杂初始化、需要控制实例化次数
代码侵入性 有(需要加注解) 无侵入
灵活性 一般 很高(可写任意初始化逻辑)
推荐原则 优先使用自动化(约定优于配置) 自动化无法满足时使用

四、完整小示例

java 复制代码
@Component
public class UserService {
    public void save() {
        System.out.println("User saved");
    }
}

@Configuration
@ComponentScan("com.example")
public class JavaConfig {
    // 可额外定义 @Bean
}

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
        UserService service = ctx.getBean(UserService.class);
        service.save();
    }
}
相关推荐
努力写A题的小菜鸡4 小时前
PyTorch 两种卷积写法彻底对比:F.conv2d 函数式 vs nn.Conv2d 类实战(超详细入门笔记)
python
golfscript4 小时前
Playwright Python:微软出的浏览器自动化库
python·其他·microsoft·自动化
charliedev4 小时前
Jedi:Python 自动补全与静态分析的实用工具
开发语言·python·其他
装不满的克莱因瓶4 小时前
自然语言处理中的分词——从语言切分到模型输入的第一步
人工智能·pytorch·python·深度学习·ai·自然语言处理
hnxaoli5 小时前
统信程序(十二)档案归档文件管理
python
雪宫街道5 小时前
SpringBoot 向 IOC 容器注册组件的两种姿势:@Configuration 与 @Import
java·spring boot·后端·spring
love530love5 小时前
2026年终极防坑指南:基于 EPGF 架构彻底“本地化” UV 环境与工具
人工智能·windows·python·架构·devops·uv·epgf
财经资讯数据_灵砚智能5 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(日间)2026年6月12日
人工智能·python·ai·信息可视化·自然语言处理·ai编程·灵砚智能
江华森5 小时前
Python 3 实战教程:从零基础到项目实战
开发语言·python
Wonderful U5 小时前
Python+Django实战|在线音乐分享平台:音乐上传、歌手专辑管理、在线播放、自定义歌单、收藏点赞、评论互动
开发语言·python·django