Spring注解配置
外观
Spring注解配置[编辑 | 编辑源代码]
介绍[编辑 | 编辑源代码]
Spring注解配置是Spring框架中基于Java注解的依赖注入(DI)和组件管理方式,它允许开发者通过声明式注解替代传统的XML配置。作为Spring IoC容器的核心特性之一,注解配置显著简化了Bean的定义、依赖关系管理和生命周期控制,是现代Spring应用开发的推荐实践。
核心优势[编辑 | 编辑源代码]
- 简洁性:减少XML配置的冗余代码
- 可读性:注解直接嵌入在类定义中,逻辑更直观
- 开发效率:支持IDE自动补全和编译时检查
- 灵活性:可与XML配置混合使用
基础注解[编辑 | 编辑源代码]
组件扫描[编辑 | 编辑源代码]
启用注解配置需先声明组件扫描,告知Spring在哪些包中查找带注解的类:
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
// 配置类内容
}
核心注解说明[编辑 | 编辑源代码]
注解 | 作用 | 等效XML |
---|---|---|
@Component |
通用组件标记 | <bean id="..." class="..."/>
|
@Service |
标记服务层组件 | - |
@Repository |
标记数据访问层组件 | - |
@Controller |
标记控制器组件 | - |
@Autowired |
自动依赖注入 | <property name="..." ref="..."/>
|
@Configuration |
声明配置类 | - |
依赖注入详解[编辑 | 编辑源代码]
字段注入[编辑 | 编辑源代码]
最简洁的注入方式,直接作用于成员变量:
@Service
public class OrderService {
@Autowired
private PaymentService paymentService;
}
构造器注入[编辑 | 编辑源代码]
Spring 4.3+推荐方式,适合强制依赖:
@Service
public class UserService {
private final UserRepository repository;
@Autowired // Spring 4.3+可省略
public UserService(UserRepository repository) {
this.repository = repository;
}
}
Setter注入[编辑 | 编辑源代码]
适用于可选依赖:
@Controller
public class ProductController {
private ProductService productService;
@Autowired
public void setProductService(ProductService productService) {
this.productService = productService;
}
}
高级配置[编辑 | 编辑源代码]
条件化Bean注册[编辑 | 编辑源代码]
使用@Conditional
实现环境相关的Bean创建:
@Bean
@Conditional(ProdEnvironmentCondition.class)
public DataSource prodDataSource() {
return new ProductionDataSource();
}
生命周期回调[编辑 | 编辑源代码]
通过注解管理Bean生命周期:
@Component
public class CacheManager {
@PostConstruct
public void initCache() {
// 初始化逻辑
}
@PreDestroy
public void clearCache() {
// 清理逻辑
}
}
实际案例[编辑 | 编辑源代码]
电商系统示例[编辑 | 编辑源代码]
实现代码:
@Repository
public class JpaProductRepository implements ProductRepository {
// 数据库操作实现
}
@Service
public class ProductService {
private final ProductRepository productRepository;
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public void updateStock(String productId, int quantity) {
Product product = productRepository.findById(productId);
product.setStock(quantity);
productRepository.save(product);
}
}
最佳实践[编辑 | 编辑源代码]
1. 优先使用构造器注入:保证依赖不可变,避免NPE 2. 限定组件扫描范围:避免不必要的性能开销 3. 避免过度使用字段注入:不利于测试和不变性 4. 组合使用@Primary和@Qualifier:解决相同类型多个实现的冲突
混合配置示例[编辑 | 编辑源代码]
@Configuration
@ImportResource("classpath:legacy-config.xml")
@ComponentScan(basePackages = "com.example.new")
public class HybridConfig {
@Bean
@Primary
public DataSource dataSource() {
// 新式数据源配置
}
}
常见问题[编辑 | 编辑源代码]
Q: 如何解决多个同类型Bean的冲突?
A: 使用@Qualifier
指定具体实现:
@Autowired
@Qualifier("mysqlDataSource")
private DataSource dataSource;
Q: 注解配置与XML配置的性能差异? A: 运行时性能无显著差异,注解配置在启动时可能有轻微解析开销
数学表示[编辑 | 编辑源代码]
Spring IoC容器的依赖关系可表示为有向图:
容器需确保图中无循环依赖,即满足: