1.3 IoC容器核心机制
1.3.1 Bean生命周期全流程解析(深度源码级)
完整生命周期流程图:
关键阶段代码演示:
public class LifecycleBean implements
BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean {
private String beanName;
// 1. Aware接口注入
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("BeanNameAware: "+name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("BeanFactoryAware注入完成");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
System.out.println("ApplicationContextAware注入完成");
}
// 2. 初始化回调
@PostConstruct
public void customInit() {
System.out.println("@PostConstruct方法执行");
}
@Override
public void afterPropertiesSet() {
System.out.println("InitializingBean.afterPropertiesSet执行");
}
public void xmlInit() {
System.out.println("XML定义的init-method执行");
}
// 3. 销毁回调
@PreDestroy
public void customDestroy() {
System.out.println("@PreDestroy方法执行");
}
@Override
public void destroy() {
System.out.println("DisposableBean.destroy执行");
}
public void xmlDestroy() {
System.out.println("XML定义的destroy-method执行");
}
}
// 配置类
@Configuration
public class LifecycleConfig {
@Bean(initMethod = "xmlInit", destroyMethod = "xmlDestroy")
public LifecycleBean lifecycleBean() {
return new LifecycleBean();
}
@Bean
public static BeanPostProcessor customProcessor() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("BeanPostProcessor前置处理: "+beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("BeanPostProcessor后置处理: "+beanName);
return bean;
}
};
}
}
控制台输出顺序:
BeanNameAware: lifecycleBean
BeanFactoryAware注入完成
ApplicationContextAware注入完成
BeanPostProcessor前置处理: lifecycleBean
@PostConstruct方法执行
InitializingBean.afterPropertiesSet执行
XML定义的init-method执行
BeanPostProcessor后置处理: lifecycleBean
... [容器运行中]
@PreDestroy方法执行
DisposableBean.destroy执行
XML定义的destroy-method执行
1.3.2 依赖注入的六种实现方式(企业级最佳实践)
注入方式对照表:
注入方式 | 实现形式 | 适用场景 | 注意事项 |
---|---|---|---|
构造器注入 | @Autowired构造函数 | 强制依赖、不可变对象 | 解决循环依赖的首选方式 |
Setter注入 | @Autowired set方法 | 可选依赖、需要重新配置 | 避免在并发场景下修改 |
字段注入 | @Autowired字段 | 快速开发、简单场景 | 不利于单元测试 |
方法注入 | @Bean工厂方法 | 复杂对象创建逻辑 | 需配合@Configuration使用 |
接口回调注入 | ApplicationContextAware | 获取容器基础设施 | 增加代码耦合度 |
查找方法注入 | @Lookup注解 | 原型Bean注入单例Bean | 需要CGLIB代理 |
构造器注入最佳实践:
@Service
public class OrderService {
private final PaymentService paymentService;
private final InventoryService inventoryService;
// 显式构造器注入
@Autowired
public OrderService(PaymentService paymentService,
InventoryService inventoryService) {
this.paymentService = paymentService;
this.inventoryService = inventoryService;
}
}
// 解决循环依赖方案
@Configuration
public class CircularDependencyConfig {
@Bean
@Lazy
public ServiceA serviceA(ServiceB serviceB) {
return new ServiceA(serviceB);
}
@Bean
@Lazy
public ServiceB serviceB(ServiceA serviceA) {
return new ServiceB(serviceA);
}
}
查找方法注入实战:
@Component
@Scope("prototype")
public class PrototypeBean {
private static int count = 0;
private final int id;
public PrototypeBean() {
this.id = ++count;
}
public void printId() {
System.out.println("PrototypeBean ID: " + id);
}
}
@Component
public class SingletonBean {
// 每次调用获得新的原型Bean
@Lookup
public PrototypeBean getPrototypeBean() {
return null; // 实际由CGLIB实现
}
public void execute() {
PrototypeBean bean = getPrototypeBean();
bean.printId();
}
}
1.3.3 自动装配的智能决策机制
自动装配冲突解决策略:
企业级配置案例:
// 主数据源配置
@Configuration
public class PrimaryDataSourceConfig {
@Bean
@Primary
public DataSource mainDataSource() {
return DataSourceBuilder.create()
.url("jdbc:mysql://master:3306/core")
.username("admin")
.password("secure123")
.build();
}
@Bean
public DataSource reportDataSource() {
return DataSourceBuilder.create()
.url("jdbc:mysql://replica:3306/report")
.username("readonly")
.password("readonly123")
.build();
}
}
// 业务服务层
@Service
public class ReportService {
private final DataSource dataSource;
// 明确指定非主数据源
public ReportService(@Qualifier("reportDataSource") DataSource dataSource) {
this.dataSource = dataSource;
}
}
自动装配异常处理方案:
// 1. 使用Optional避免依赖不存在
@Autowired
public void setOptionalDependency(Optional<SomeService> service) {
service.ifPresent(s -> this.service = s);
}
// 2. 自定义缺失Bean处理
@Bean
@ConditionalOnMissingBean
public DefaultCacheManager defaultCache() {
return new DefaultCacheManager();
}
// 3. 集合类型安全注入
@Autowired
public void setStrategies(List<BusinessStrategy> strategies) {
this.strategyMap = strategies.stream()
.collect(Collectors.toMap(
s -> s.getClass().getSimpleName(),
Function.identity()
));
}
1.3.4 条件化Bean配置实战
多环境数据源切换方案:
// 条件判断类
public class EnvCondition implements Condition {
@Override
public boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {
String env = context.getEnvironment()
.getProperty("app.env", "dev");
return "prod".equals(env);
}
}
// 生产环境配置
@Configuration
@Conditional(EnvCondition.class)
public class ProdDataSourceConfig {
@Bean
public DataSource prodDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://prod-db:3306/core");
config.setUsername("prod_user");
config.setPassword(System.getenv("DB_PROD_PASS"));
config.setConnectionTimeout(3000);
return new HikariDataSource(config);
}
}
// 开发环境配置
@Profile("dev")
@Configuration
public class DevDataSourceConfig {
@Bean
public DataSource devDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.build();
}
}
条件注解组合使用:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Conditional(OnCloudPlatformCondition.class)
@Conditional(OnKubernetesEnvCondition.class)
public @interface ConditionalOnCloudKubernetes {}
// 云原生环境专属配置
@Configuration
@ConditionalOnCloudKubernetes
public class CloudNativeConfig {
@Bean
public ServiceDiscovery serviceDiscovery() {
return new KubernetesServiceDiscovery();
}
}