@Autowired
是 Spring 框架中用于实现 依赖注入(Dependency Injection, DI) 的核心注解之一。它的核心作用是自动装配 Bean,简化代码中对依赖对象的显式获取和管理。以下是详细解析:
new
或 ApplicationContext.getBean()
创建对象。@Qualifier
注解,则优先按名称匹配;若存在 @Primary
注解,则优先选择主 Bean。直接在字段上标注 @Autowired
,Spring 会自动注入匹配的 Bean。
@Service
public class UserService {
@Autowired
private UserRepository userRepository; // 自动注入 UserRepository 类型的 Bean
}
在构造器上标注 @Autowired
,Spring 会通过构造器参数注入依赖。
@Service
public class OrderService {
private final PaymentService paymentService;
@Autowired // 可省略(Spring 4.3+ 单构造器时自动识别)
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
在 Setter 方法上标注 @Autowired
,Spring 会在对象创建后调用该方法注入依赖。
@Service
public class ProductService {
private InventoryService inventoryService;
@Autowired
public void setInventoryService(InventoryService inventoryService) {
this.inventoryService = inventoryService;
}
}
@Qualifier
指定 Bean 名称当存在多个相同类型的 Bean 时,通过 @Qualifier
明确指定要注入的 Bean。
@Autowired
@Qualifier("mysqlDataSource") // 注入名为 "mysqlDataSource" 的 DataSource
private DataSource dataSource;
@Primary
标记主 Bean当存在多个相同类型的 Bean 时,用 @Primary
标记默认优先使用的 Bean。
@Configuration
public class AppConfig {
@Bean
@Primary
public DataSource mysqlDataSource() {
// 返回 MySQL 数据源
}
@Bean
public DataSource redisDataSource() {
// 返回 Redis 数据源
}
}
通过 @Autowired(required = false)
标记可选依赖,若容器中没有匹配的 Bean,则注入 null
。
@Autowired(required = false)
private Logger logger; // 如果容器中没有 Logger Bean,则 logger 为 null
@Lazy
延迟加载。final
字段),且更易于单元测试。NoSuchBeanDefinitionException
异常@ComponentScan
)、Bean 名称或类型是否匹配。@Qualifier
指定名称,或用 @Primary
标记主 Bean。Circular dependency
。@Lazy
延迟初始化。注解 | 作用范围 | 适用场景 |
---|---|---|
@Autowired |
Spring 框架 | 自动装配 Bean,默认按类型匹配 |
@Resource |
JSR-250(Java 标准) | 按名称或类型匹配(优先名称) |
@Inject |
JSR-330(Java 依赖注入) | 功能类似 @Autowired |
@Autowired
等注解,注入依赖的其他 Bean。@PostConstruct
方法或实现 InitializingBean
接口。@PreDestroy
方法或实现 DisposableBean
接口。@Autowired
等注解,生成依赖关系元数据。// 伪代码示例:Spring 容器查找 Bean 的逻辑
Object getBean(String name, Class<?> requiredType) {
// 1. 检查缓存中是否存在 Bean
// 2. 根据类型(requiredType)匹配 Bean
// 3. 若存在多个,根据名称或 @Primary 选择
// 4. 处理代理对象(如 AOP)
return beanInstance;
}
对比维度 | 构造器注入 | 字段注入 |
---|---|---|
可测试性 | ✅ 可直接通过构造器传入 Mock 对象 | ❌ 需依赖反射或 Spring 上下文 |
不变性 | ✅ 依赖项可为 final 字段 |
❌ 字段通常为非 final |
代码可读性 | ✅ 显式声明依赖,一目了然 | ❌ 依赖隐藏在字段中,需查看注解 |
循环依赖支持 | ❌ 构造器注入无法解决循环依赖 | ✅ 字段注入可通过三级缓存解决 |
结论:优先使用构造器注入,仅在无法避免循环依赖时使用字段注入。
@Profile
实现环境隔离根据不同环境(如 dev/test/prod)注入不同 Bean:
@Configuration
@Profile("dev")
public class DevConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().build();
}
}
@Configuration
@Profile("prod")
public class ProdConfig {
@Bean
public DataSource dataSource() {
return new JndiObjectFactoryBean();
}
}
@Conditional
)根据条件动态决定是否创建 Bean:
@Bean
@Conditional(OnDatabaseCondition.class) // 自定义条件类
public DatabaseService databaseService() {
return new DatabaseService();
}
// 自定义条件类
public class OnDatabaseCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return "mysql".equals(context.getEnvironment().getProperty("db.type"));
}
}
@Autowired
在 WebFlux
中,@Autowired
可注入 Reactive
类型(如 Mono
/Flux
):
@Service
public class ReactiveService {
private final WebClient webClient;
public ReactiveService(WebClient webClient) {
this.webClient = webClient;
}
public Mono<String> fetchData() {
return webClient.get().uri("/api/data").retrieve().bodyToMono(String.class);
}
}
在 Kotlin 中,@Autowired
可与挂起函数结合使用:
@Service
class UserService(
private val userRepository: UserRepository // 构造器注入
) {
suspend fun getUserById(id: Long): User? {
return userRepository.findById(id)
}
}
@Autowired
在泛型中的使用通过 ResolvableType
解析泛型类型:
@Service
public class GenericService<T> {
private final JpaRepository<T, Long> repository;
@Autowired
public GenericService(JpaRepository<T, Long> repository) {
this.repository = repository;
}
}
@Autowired
的滥用@Autowired
,改用 ApplicationContextAware
。@Lazy
延迟加载非必需依赖:@Autowired
@Lazy
private ExpensiveService expensiveService; // 仅在首次使用时初始化
CachedIntrospectionResults
缓存反射数据,提升注入性能。@Service
public class ServiceA {
private final ServiceB serviceB;
public ServiceA(@Lazy ServiceB serviceB) { // 使用 @Lazy 打破循环
this.serviceB = serviceB;
}
}
@Service
public class ServiceB {
private final ServiceA serviceA;
public ServiceB(ServiceA serviceA) {
this.serviceA = serviceA;
}
}
@ComponentScan
的扫描范围不重叠。@Qualifier
消除歧义:@Autowired
@Qualifier("moduleADataSource") // 显式指定模块前缀
private DataSource dataSource;
@Autowired
通过自定义注解减少重复代码:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Autowired // 继承 @Autowired 行为
public @interface MyAutowired {
String value() default "";
}
// 使用自定义注解
public class MyService {
@MyAutowired("customBean")
private MyBean myBean;
}
自动注入 Repository
接口的实现:
@Repository
public interface UserRepository extends JpaRepository<User, Long> {}
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
注入安全相关的依赖:
@Service
public class AuthService {
private final UserDetailsService userDetailsService;
@Autowired
public AuthService(@Qualifier("customUserDetailsService") UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
}
批量任务中的依赖注入:
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Bean
public Job job(JobRepository jobRepository, Step step) {
return new JobBuilder("job", jobRepository)
.start(step)
.build();
}
}
@Autowired
是 Spring 实现 IoC 的关键工具,通过自动化依赖管理显著提升开发效率。@Autowired
可能会与新的 API(如 Supplier
/Function
)更深度整合。@Qualifier
和 @Primary
解决冲突。@Lazy
和条件化注入优化设计。通过灵活运用 @Autowired
,开发者可以构建高内聚、低耦合的 Spring 应用,充分发挥框架的潜力。