Spring: @Component 与 @Bean 的对比

Spring: @Component 与 @Bean 的对比

技术背景

在 Spring 框架中,管理 Bean 是核心功能之一。早期,Spring 通过 XML 文件来定义和配置 Bean,但随着版本的发展,为了提高开发效率和代码的简洁性,引入了注解的方式。@Component 注解在 Spring 2.5 版本被引入,它借助类路径扫描功能,能够摆脱 XML 配置文件来定义 Bean;而 @Bean 注解则在 Spring 3.0 版本引入,可与 @Configuration 注解配合使用,完全摒弃 XML 文件,采用 Java 代码进行配置。

实现步骤

@Component 的使用

  1. 在类上添加 @Component 注解,Spring 会自动扫描并将该类注册为 Bean。
1
2
3
4
5
6
import org.springframework.stereotype.Component;

@Component
public class SomeClass {
// 类的具体实现
}
  1. 在配置类上添加 @ComponentScan 注解,指定扫描的包路径。
1
2
3
4
5
6
7
8
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// 配置类的其他配置
}

@Bean 的使用

  1. 创建一个配置类,使用 @Configuration 注解标记。
1
2
3
4
5
6
7
8
9
10
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
@Bean
public SomeClass someClass() {
return new SomeClass();
}
}
  1. 在需要使用该 Bean 的地方,通过 ApplicationContext 获取 Bean 实例。
1
2
3
4
5
6
7
8
9
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SomeClass someClass = context.getBean(SomeClass.class);
// 使用 someClass 实例
}
}

核心代码

使用 @Component 注解的类

1
2
3
4
5
6
7
8
import org.springframework.stereotype.Component;

@Component
public class UserService {
public void doSomething() {
System.out.println("UserService is doing something.");
}
}

使用 @Bean 注解的配置类

1
2
3
4
5
6
7
8
9
10
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

获取 Bean 实例的代码

1
2
3
4
5
6
7
8
9
10
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);
userService.doSomething();
context.close();
}
}

最佳实践

  • 使用 @Component:当开发自己的应用代码,且希望 Spring 自动扫描并注册 Bean 时,优先使用 @Component 注解。例如,服务层、数据访问层的类可以分别使用 @Service@Repository 注解,它们是 @Component 的衍生注解。
1
2
3
4
5
6
7
8
9
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
@Override
public void doSomething() {
System.out.println("UserServiceImpl is doing something.");
}
}
  • 使用 @Bean:当需要集成第三方库的类,或者需要手动控制 Bean 的创建和配置时,使用 @Bean 注解。例如,配置数据源、视图解析器等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;

@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("root");
dataSource.setPassword("password");
return dataSource;
}
}

常见问题

能否在除了 @Configuration 类之外的地方使用 @Bean 注解?

可以,@Bean 注解也可以在 @Component 注解的类中使用,但这种方式被称为“轻量级模式”,不推荐使用。

如果没有第三方类的源代码,如何使用 @Bean 注解创建 Bean?

即使没有第三方类的源代码,仍然可以通过 @Bean 注解将其封装为 Spring Bean。在配置类中,使用 @Bean 注解的方法手动创建该类的实例并返回。

1
2
3
4
5
6
7
8
9
10
11
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.example.ThirdPartyClass;

@Configuration
public class AppConfig {
@Bean
public ThirdPartyClass thirdPartyClass() {
return new ThirdPartyClass();
}
}

@Component@Bean 能否一起使用?

可以。@Component 用于自动扫描和注册 Bean,而 @Bean 可以用于手动配置一些特殊的 Bean。它们可以在同一个项目中配合使用,以满足不同的需求。


Spring: @Component 与 @Bean 的对比
https://119291.xyz/posts/2025-04-21.spring-component-vs-bean-comparison/
作者
ww
发布于
2025年4月22日
许可协议