Spring 的常用注入方式有哪些

Spring 的常用注入方式有哪些

构造器注入

1
2
3
4
5
6
7
8
9
@Component
public class UserService {
    private final UserRepository userRepository;

    @Autowired  // Spring 4.3+ 如果只有一个构造器,可以省略 @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}
1
2
3
4
5
@Component
@AllArgsConstructor
public class UserService {
    private final UserRepository userRepository;
}

优点:

  • 依赖是 final,不可变,线程安全
  • 依赖在对象创建时就完全注入,保证对象完整性
  • 适合强制依赖(必须有)

缺点:

  • 如果依赖很多,构造器参数会很长(可用 Lombok 简化)

基于 Java 配置的依赖注入方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Configuration
public class AppConfig {

    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }

    @Bean
    public UserService userService(UserRepository userRepository) {
        // Spring 会自动把 userRepository() 的返回值注入到这里
        return new UserService(userRepository);
    }
}

说明:

  • userService()方法的参数UserRepository会由 Spring 自动注入(按类型匹配)。
  • 这种方式是 显式构造器注入,依赖关系清晰。

Setter 方法注入

1
2
3
4
5
6
7
8
9
@Component
public class UserService {
    private UserRepository userRepository;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}

优点:

  • 可选依赖(可以不注入)
  • 代码可读性好

缺点:

  • 对象创建后依赖可能为空(不安全)
  • 依赖可变,可能被修改

基于 Java 配置的依赖注入方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class AppConfig {

    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }

    @Bean
    public UserService userService() {
        UserService userService = new UserService();
        userService.setUserRepository(userRepository());
        return userService;
    }
}

说明:

  • 这种方式适合可选依赖。
  • 缺点是依赖关系不如构造器注入直观。

字段注入

直接在字段上使用@Autowired或者@Resource注入依赖。

1
2
3
4
5
6
7
8
9
10
11
@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;
}

@Component
public class UserService {
    @Resource
    private UserRepository userRepository;
}

优点:

  • 代码简洁
  • 不需要构造器或 setter

缺点:

  • 依赖不可见(不利于单元测试)
  • 违反依赖倒置原则(DIP)
  • 不利于不可变设计
本文作者:
本文链接: https://hgnulb.github.io/blog/2026/56134052
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!