Spring: @Component 与 @Bean 的对比 技术背景 在 Spring 框架中,管理 Bean 是核心功能之一。早期,Spring 通过 XML 文件来定义和配置 Bean,但随着版本的发展,为了提高开发效率和代码的简洁性,引入了注解的方式。@Component
注解在 Spring 2.5 版本被引入,它借助类路径扫描功能,能够摆脱 XML 配置文件来定义 Bean;而 @Bean
注解则在 Spring 3.0 版本引入,可与 @Configuration
注解配合使用,完全摒弃 XML 文件,采用 Java 代码进行配置。
实现步骤 @Component 的使用 在类上添加 @Component
注解,Spring 会自动扫描并将该类注册为 Bean。 1 2 3 4 5 6 import org.springframework.stereotype.Component;@Component public class SomeClass { }
在配置类上添加 @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 的使用 创建一个配置类,使用 @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 (); } }
在需要使用该 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); } }
核心代码 使用 @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。它们可以在同一个项目中配合使用,以满足不同的需求。