欢迎光临
我们一直在努力

一文讲清楚Spring的自动装配原理和实现方式

Spring 实现自动装配(Autowiring)的核心原理是 IoC 容器基于类型或名称匹配,通过反射机制动态解析并注入依赖对象。其本质是 控制反转(IoC)​ 的具体实践,将依赖关系的维护从代码中剥离,交由 Spring 容器统一管理。

01-自动装配的核心原理

1.1 依赖解析机制

  • 类型匹配:容器根据目标 Bean 的依赖类型(如 UserService中的 UserRepository字段类型),在容器中查找匹配的 Bean

  • 名称匹配:若开启 byName模式,则根据 字段名 / 参数名 查找同名的 Bean

  • 注解驱动:@Autowired等注解 触发容器按类型扫描依赖

1.2 反射注入

        通过 Java 反射 API(Class.getDeclaredField(),  Method.invoke())动态设置字段值或调用 Setter 方法

伪代码示例:

Field field = target.getClass().getDeclaredField("userRepo");
field.setAccessible(true);
field.set(target, beanFactory.getBean(UserRepository.class)); // 注入依赖

1.3 循环依赖处理

三层缓存机制(仅限单例Bean):

  • singletonObjects:完整 Bean 缓存;
  • earlySingletonObjects:提前暴露的不完整 Bean;
  • singletonFactories:生成早期 Bean 的工厂

构造器注入的循环依赖无法解决(会抛异常)

想详细了解循环依赖可以看下这篇文章:一文详解Spring Bean的循环依赖问题及解决方案(三级缓存)-CSDN博客

02-Spring 实现自动装配的方式

2.1 XML 配置

传统方式,现在已经很少使用

<!– 全局启用 byType 自动装配 –>
<beans default-autowire="byType">
<bean id="userService" class="com.example.UserService"/>
<bean id="userRepo" class="com.example.UserRepositoryImpl"/> <!– 按类型匹配 –>
</beans>

<!– 单个 Bean 指定构造器注入 –>
<bean id="orderService" class="com.example.OrderService" autowire="constructor"/>

2.2 注解驱动(主流)

01-@Autowired 注解(Spring 原生)

类型自动装配,可配合 @Qualifier指定 Bean 名称,支持 required = false(可选依赖,不存在时不注入)

1.1 字段注入

@Service
public class UserService {

@Autowired // 自动注入
private UserRepository userRepository;

@Autowired
private EmailService emailService;

public void registerUser(String username) {
userRepository.save(username);
emailService.sendWelcomeEmail(username);
}
}

@Repository
public class UserRepository {
public void save(String user) {
System.out.println("保存用户: " + user);
}
}

@Service
public class EmailService {
public void sendWelcomeEmail(String user) {
System.out.println("发送欢迎邮件给: " + user);
}
}

1.2 构造器注入(推荐)

@Service
public class OrderService {

private final PaymentService paymentService;
private final InventoryService inventoryService;

@Autowired // Spring 4.3+ 可省略
public OrderService(PaymentService paymentService,
InventoryService inventoryService) {
this.paymentService = paymentService;
this.inventoryService = inventoryService;
}

public void processOrder(Order order) {
// 使用注入的服务
}
}

1.3 Setter 方法注入

@Service
public class ProductService {

private DiscountService discountService;
private TaxCalculator taxCalculator;

@Autowired
public void setDiscountService(DiscountService discountService) {
this.discountService = discountService;
}

@Autowired
public void setTaxCalculator(TaxCalculator taxCalculator) {
this.taxCalculator = taxCalculator;
}
}

02-@Resource(JSR-250)

默认按名称装配,其次按类型

import javax.annotation.Resource;

@Service
public class ShoppingCartService {

@Resource // 按名称注入,等价于 @Autowired + @Qualifier
private ProductRepository productRepository;

@Resource(name = "creditCardPayment") // 指定bean名称
private PaymentProcessor paymentProcessor;

@Resource(type = OrderValidator.class) // 按类型注入
private OrderValidator orderValidator;
}

03-@Inject(JSR-330)

类似 @Autowired,需额外依赖 @Named 注解指定名称

import javax.inject.Inject;
import javax.inject.Named;

@Component
public class ReportGenerator {

@Inject // 与 @Autowired 功能相似
private DataSource dataSource;

@Inject
@Named("pdfFormatter") // 指定bean名称
private ReportFormatter pdfFormatter;

@Inject
public ReportGenerator(@Named("excelFormatter") ReportFormatter formatter) {
this.excelFormatter = formatter;
}
}

2.3 Java Config 配置

相当于传统Spring中的XML配置文件

@Configuration
public class AppConfig {
@Bean
public UserService userService(UserRepository userRepo) { // 参数自动注入
return new UserService(userRepo);
}

@Bean
public UserRepository mysqlRepo() {
return new MysqlUserRepository();
}
}

03-核心流程详解

3.1 容器启动

1. 加载配置元数据(XML / 注解 / Java Config);

2. 解析 Bean 定义,注册到 DefaultListableBeanFactory

3.2 依赖收集

扫描每个 Bean 的依赖描述符(如 @Autowired字段、构造器参数)

3.3 依赖注入

步骤 1:根据类型查找候选 Bean(从 BeanFactory中检索);

步骤 2:处理歧义性(使用 @Primary或 @Qualifier);

步骤 3通过反射注入依赖(字段 / 构造器 / Setter)

3.4 生命周期回调

注入后执行 @PostConstruct / InitializingBean.afterPropertiesSet() —> 初始化Bean时调用

04-使用建议

优先使用 构造器注入(不可变依赖、易测试);

避免字段注入(不利于测试和封装)

赞(0)
未经允许不得转载:171主机测评 » 一文讲清楚Spring的自动装配原理和实现方式
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址