注入Java Bean的方式

简介: 本文总结了 Spring Boot 中常见的 Bean 注入方式,包括字段注入(`@Autowired`)、构造器注入(推荐)、Setter 方法注入、`@Resource` 按名称注入、`@Bean` 定义复杂 Bean、`@Value` 注入配置值、XML 配置、`ApplicationContextAware` 手动获取 Bean 以及 JSR-330 的 `@Inject`。同时分析了 Setter 注入逐渐被淡化的原因,强调构造器注入的不可变性和安全性优势,并推荐结合 Lombok 简化代码。文章还提供了按需选择注解的建议和最佳实践,帮助开发者根据场景选择合适的依赖注入方式。

Spring Boot 中注入 Bean 的常见方式如下,每种方式适用于不同的场景:


1. @Autowired 注解(字段注入)

  • 说明:按类型自动装配,可作用于构造器、Setter 方法、字段或普通方法。
  • 场景:大多数情况下的依赖注入。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Service
public class MyService {
    @Autowired // 字段注入
    private MyRepository repository;
}

2. 构造器注入(推荐)

  • 说明:通过构造器注入依赖,Spring 4.3+ 中若类只有单个构造器,可省略 @Autowired。
  • 优势:强制依赖不可变,避免空指针。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Service
public class MyService {
    private final MyRepository repository;

    public MyService(MyRepository repository) { // 自动注入
        this.repository = repository;
    }
}

3. @Resource 注解

  • 说明:按名称注入(JSR-250 规范),默认按字段名或方法名匹配 Bean。
  • 场景:需明确指定 Bean 名称时。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Service
public class MyService {
    @Resource(name = "myRepositoryImpl")
    private MyRepository repository;
}

4. @Bean 方法(Java 配置类)

  • 说明:在 @Configuration 类中定义 @Bean 方法,返回对象由 Spring 管理。
  • 场景:配置第三方库组件或复杂 Bean。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return new HikariDataSource();
    }
}

5. @Value 注解

  • 说明:注入配置文件属性或 SpEL 表达式。
  • 场景:注入简单值(如字符串、数字)或动态表达式。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Component
public class MyComponent {
    @Value("${app.timeout:1000}") // 注入配置,默认值 1000
    private int timeout;
}

6. XML 配置(传统方式)

  • 说明:通过 XML 定义 Bean,需配合 @ImportResource 导入。
  • 场景:遗留项目迁移或混合配置。
  • 示例:

xml

  • 体验AI代码助手
  • 代码解读
  • 复制代码
<!-- applicationContext.xml -->
<bean id="myBean" class="com.example.MyBean"/>

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@SpringBootApplication
@ImportResource("classpath:applicationContext.xml")
public class App { ... }

7. ApplicationContextAware 手动获取

  • 说明:实现接口获取 ApplicationContext,直接调用 getBean()。
  • 场景:非 Spring 管理类中动态获取 Bean(不推荐常规使用)。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Component
public class MyBean implements ApplicationContextAware {
    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext context) {
        this.context = context;
    }

    public void useBean() {
        MyService service = context.getBean(MyService.class);
    }
}

8. JSR-330 的 @Inject 注解

  • 说明:与 @Autowired 功能类似,需引入 javax.inject 依赖。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Service
public class MyService {
    @Inject
    private MyRepository repository;
}

9. Setter 方法注入

  • 说明:通过 @Autowired 注解标记在 Setter 方法上,Spring 会调用该方法注入依赖。
  • 场景:
  • 可选依赖:依赖不是必须的(例如有默认实现)。
  • 动态重新注入:需要运行时更换依赖(较少见)。
  • 示例:

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Service
public class MyService {
    private MyRepository repository;

    @Autowired // Setter 方法注入
    public void setRepository(MyRepository repository) {
        this.repository = repository;
    }
}

Setter 方法注入是 Spring 中另一种常见的依赖注入方式,尤其是在早期 Spring 版本中广泛使用。可能因为它在现代 Spring Boot 项目中逐渐被构造器注入取代(官方推荐)


为什么 Setter 注入逐渐被淡化?

  1. 不可变性与安全性
  • 构造器注入能确保依赖在对象创建时就被初始化,避免 NullPointerException。
  • Setter 注入允许依赖在对象创建后修改(除非代码刻意限制),可能破坏不变性。
  1. 代码简洁性
  • 构造器注入无需写 Setter 方法,减少样板代码(尤其配合 Lombok @RequiredArgsConstructor)。
  1. 框架演进
  • Spring 官方自 4.x 起推荐构造器注入,明确依赖的强制性,提升组件可靠性。

Setter 注入的合理使用场景

  • 可选依赖:依赖可能为 null,且有默认处理逻辑。

java

  • 体验AI代码助手
  • 代码解读
  • 复制代码
@Autowired(required = false) // 依赖不存在时不报错
public void setOptionalDependency(OptionalDependency dep) {
    this.dep = dep != null ? dep : new DefaultDependency();
}
  • 循环依赖:某些复杂场景下,Setter 注入可配合 @Lazy 解决循环依赖(但设计上应尽量避免循环依赖)。

9. 构造器注入最新方式

通过类的构造器注入依赖,结合 Lombok 的 @RequiredArgsConstructor 可自动生成构造器。

java

体验AI代码助手

代码解读

复制代码

@Service
@RequiredArgsConstructor // Lombok 自动生成构造器(注入方式)
public class UserService {
    private final UserRepository userRepository; // 依赖
}

为什么 Lombok 属于依赖注入?

  • Lombok 的作用:通过 @RequiredArgsConstructor 自动生成包含 final 字段的构造器,减少了手动编写构造器的代码量。
  • Spring 的配合:当类被声明为 Bean(如 @Service)后,Spring 会自动通过生成的构造器完成依赖注入。
  • 本质:Lombok 只是简化了依赖注入的代码编写,不参与 Bean 的声明过程。

  • 优先使用构造器注入:强制依赖、不可变性、代码简洁性。
  • 按需使用 Setter 注入:可选依赖或特殊场景。
  • 避免滥用字段注入:虽然方便,但隐藏依赖关系,不利于测试和维护。

总结

  • 推荐方式:构造器注入(不可变依赖) + @Autowired(可选依赖)。
  • 避免使用:字段注入(不利于测试)和 ApplicationContextAware(破坏控制反转)。
  • 按需选择:@Resource(按名称注入)、@Value(配置值)或 @Bean(复杂配置)。
  • Lombok 属于依赖注入的优化工具
  • 最佳实践:使用 @Component 等注解声明 Bean + 构造器注入(配合 Lombok 简化代码)。


转载来源:https://juejin.cn/post/7493866403407134746

相关文章
|
XML Java 开发者
Spring Boot中的bean注入方式和原理
Spring Boot中的bean注入方式和原理
2192 0
|
XML Java 数据库
探索 Spring Boot 中的 @Configuration 注解:核心概念与应用
【4月更文挑战第20天】在 Spring Boot 项目中,@Configuration 注解扮演了一个关键角色,它标识一个类作为配置源,这些配置用于定义和管理 Spring 应用程序中的 Bean
3149 7
|
安全 Java Spring
Spring Boot 过滤器(Filter)详解
本文详解Spring Boot中过滤器的原理与实践,涵盖Filter接口、执行流程、@Component与FilterRegistrationBean两种实现方式、执行顺序控制及典型应用场景如日志记录、权限验证。对比拦截器,突出其在Servlet容器层的通用性与灵活性,助力构建高效稳定的Web应用。
6308 1
|
JSON 安全 Java
Spring Boot 序列化、反序列化
本文介绍了Spring Boot中的序列化和反序列化。Java提供默认序列化机制,通过实现Serializable接口实现对象到字节流的转换。Spring Boot默认使用Jackson处理JSON,可通过注解和配置自定义规则。然而,序列化可能引发安全问题,建议使用白名单、数据校验和安全库。最佳实践包括使用标准机制、自定义规则及注意版本控制。文章还提醒关注性能并提供了相关参考资料。
1470 2
|
XML Java 测试技术
Spring Boot中的依赖注入和控制反转
Spring Boot中的依赖注入和控制反转
|
缓存 安全 Java
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
8109 14
Spring Boot 3 集成 Spring Security + JWT
@RequiredArgsConstructor(onConstructor=@_(@Autowired))是什么语法?
@RequiredArgsConstructor(onConstructor=@_(@Autowired))是什么语法?
763 0
|
Java 开发者 Spring
Java Springboot监听事件和处理事件
通过这些内容的详细介绍和实例解析,希望能帮助您深入理解Spring Boot中的事件机制,并在实际开发中灵活应用,提高系统的可维护性和扩展性。
1491 7
|
设计模式 Java 关系型数据库
【阿里规约】阿里开发手册解读——命名规范篇
本文中所有代码命名规范遵循《阿里规约》,从包名、类名、变量名等角度展开,详细阐述测试类、枚举类、数组、布尔型变量、方法等元素的命名规范。
【阿里规约】阿里开发手册解读——命名规范篇
|
前端开发 Java 数据格式
SpringBoot中定义Bean的几种方式
本文介绍了Spring Boot中定义Bean的多种方式,包括使用@Component、@Bean、@Configuration、@Import等注解及Java配置类。每种方式适用于不同的场景,帮助开发者高效管理和组织应用组件。
848 0