知识模块
☕ Java 知识模块
八、Spring 全家桶
Spring IOC 与 Bean 生命周期

Spring IOC 与 Bean 生命周期

IOC(控制反转)

什么是 IOC?

IOC(Inversion of Control):控制反转,将对象的创建和管理权交给 Spring 容器。

传统方式:程序主动创建对象
new UserService();
new UserDao();

IOC 方式:容器注入对象
@Autowired
private UserService userService;

IOC 容器体系

BeanFactory(顶层接口)
    └── ApplicationContext(增强接口)
            ├── ClassPathXmlApplicationContext(XML配置)
            ├── AnnotationConfigApplicationContext(注解配置)
            └── WebApplicationContext(Web环境)

BeanFactory vs ApplicationContext

特性BeanFactoryApplicationContext
初始化时机懒加载(首次使用时)预加载(容器启动时)
国际化不支持支持
事件机制不支持支持
AOP 支持需手动配置自动支持
适用场景资源受限环境企业级应用

Bean 生命周期

完整生命周期流程

1. 实例化(Instantiation)

2. 属性赋值(Populate)

3. 初始化前(BeanPostProcessor.postProcessBeforeInitialization)

4. 初始化(InitializingBean.afterPropertiesSet、init-method)

5. 初始化后(BeanPostProcessor.postProcessAfterInitialization)

6. 使用中

7. 销毁前(DestructionAwareBeanPostProcessor.postProcessBeforeDestruction)

8. 销毁(DisposableBean.destroy、destroy-method)

详细流程图

┌─────────────────────────────────────────────────────────────┐
│                      Spring 容器启动                          │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 1. 实例化 Bean                                               │
│    - 调用构造函数                                             │
│    - InstantiationAwareBeanPostProcessor.postProcessBefore   │
│      Instantiation(实例化前)                                │
│    - InstantiationAwareBeanPostProcessor.postProcessAfter    │
│      Instantiation(实例化后)                                │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 2. 属性赋值                                                   │
│    - 依赖注入(@Autowired、@Value)                           │
│    - InstantiationAwareBeanPostProcessor.postProcess         │
│      Properties(属性处理)                                   │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 3. 初始化前处理                                               │
│    - BeanNameAware.setBeanName()                             │
│    - BeanClassLoaderAware.setBeanClassLoader()               │
│    - BeanFactoryAware.setBeanFactory()                       │
│    - ApplicationContextAware.setApplicationContext()          │
│    - BeanPostProcessor.postProcessBeforeInitialization()     │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 4. 初始化                                                     │
│    - @PostConstruct                                          │
│    - InitializingBean.afterPropertiesSet()                   │
│    - 自定义 init-method                                       │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 5. 初始化后处理                                               │
│    - BeanPostProcessor.postProcessAfterInitialization()      │
│    - 此处生成 AOP 代理                                        │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 6. Bean 就绪,可使用                                          │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 7. 销毁前处理                                                 │
│    - DestructionAwareBeanPostProcessor                       │
│      .postProcessBeforeDestruction()                         │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│ 8. 销毁                                                       │
│    - @PreDestroy                                             │
│    - DisposableBean.destroy()                                │
│    - 自定义 destroy-method                                    │
└─────────────────────────────────────────────────────────────┘

代码示例

@Component
public class MyBean implements InitializingBean, DisposableBean, 
                               BeanNameAware, ApplicationContextAware {
    
    private String beanName;
    private ApplicationContext context;
    
    // 1. 构造函数
    public MyBean() {
        System.out.println("1. 构造函数");
    }
    
    // 2. 依赖注入
    @Autowired
    public void setOtherBean(OtherBean otherBean) {
        System.out.println("2. 属性注入");
    }
    
    // 3. Aware 接口回调
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("3. BeanNameAware: " + name);
    }
    
    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        this.context = ctx;
        System.out.println("3. ApplicationContextAware");
    }
    
    // 4. @PostConstruct
    @PostConstruct
    public void postConstruct() {
        System.out.println("4. @PostConstruct");
    }
    
    // 5. InitializingBean
    @Override
    public void afterPropertiesSet() {
        System.out.println("5. InitializingBean.afterPropertiesSet");
    }
    
    // 6. 自定义 init-method
    public void customInit() {
        System.out.println("6. customInit-method");
    }
    
    // 业务方法
    public void doSomething() {
        System.out.println("Bean 使用中...");
    }
    
    // 7. @PreDestroy
    @PreDestroy
    public void preDestroy() {
        System.out.println("7. @PreDestroy");
    }
    
    // 8. DisposableBean
    @Override
    public void destroy() {
        System.out.println("8. DisposableBean.destroy");
    }
    
    // 9. 自定义 destroy-method
    public void customDestroy() {
        System.out.println("9. customDestroy-method");
    }
}

BeanPostProcessor

作用

BeanPostProcessor 是 Spring 提供的扩展点,可以在 Bean 初始化前后进行自定义处理。

public interface BeanPostProcessor {
    // 初始化前
    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
    
    // 初始化后
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

常见实现

BeanPostProcessor作用
AutowiredAnnotationBeanPostProcessor处理 @Autowired 注入
CommonAnnotationBeanPostProcessor处理 @Resource、@PostConstruct、@PreDestroy
ApplicationContextAwareProcessor处理 Aware 接口
AbstractAutoProxyCreatorAOP 代理创建

自定义 BeanPostProcessor

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (bean instanceof MyBean) {
            System.out.println("初始化前处理: " + beanName);
        }
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean instanceof MyBean) {
            System.out.println("初始化后处理: " + beanName);
            // 可以返回代理对象
        }
        return bean;
    }
}

Bean 的作用域

作用域说明适用场景
singleton(默认)单例,整个容器只有一个实例无状态 Bean
prototype原型,每次获取创建新实例有状态 Bean
request每个 HTTP 请求一个实例Web 应用
session每个 HTTP Session 一个实例Web 应用
application整个 ServletContext 一个实例Web 应用
@Component
@Scope("prototype")
public class PrototypeBean {
    // 每次获取都创建新实例
}

面试高频问题

Q1: Spring Bean 的完整生命周期?

回答要点:

  1. 实例化:调用构造函数
  2. 属性赋值:依赖注入
  3. Aware 接口回调:注入容器相关信息
  4. 初始化前:BeanPostProcessor.postProcessBeforeInitialization
  5. 初始化:@PostConstruct → InitializingBean → init-method
  6. 初始化后:BeanPostProcessor.postProcessAfterInitialization(AOP 代理在此生成)
  7. 使用
  8. 销毁前:DestructionAwareBeanPostProcessor
  9. 销毁:@PreDestroy → DisposableBean → destroy-method

Q2: BeanPostProcessor 和 InstantiationAwareBeanPostProcessor 的区别?

接口作用时机用途
BeanPostProcessor初始化前后属性修改、代理创建
InstantiationAwareBeanPostProcessor实例化前后控制实例化过程、属性注入
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    // 实例化前(可以返回代理对象,跳过实例化)
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        return null;
    }
    
    // 实例化后(决定是否进行属性注入)
    default boolean postProcessAfterInstantiation(Object bean, String beanName) {
        return true;
    }
    
    // 属性注入时
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        return pvs;
    }
}

Q3: Spring 如何解决循环依赖?

回答要点:

  1. 构造器循环依赖:无法解决,抛出 BeanCurrentlyInCreationException
  2. Setter 循环依赖:通过三级缓存解决
  3. Prototype 循环依赖:无法解决

三级缓存:

// 一级缓存:完整的 Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
 
// 二级缓存:早期暴露的 Bean(未完成属性注入)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
 
// 三级缓存:Bean 工厂(用于生成早期 Bean 或代理)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

流程:

  1. 创建 A,暴露到三级缓存
  2. 注入 B,发现 B 未创建
  3. 创建 B,注入 A
  4. 从三级缓存获取 A(或其代理),放入二级缓存
  5. B 完成创建
  6. A 完成创建

Q4: 为什么三级缓存而不是两级?

关键:AOP 代理的创建时机

  • 如果只有两级缓存,需要在暴露早期引用时就确定是否需要代理
  • 三级缓存通过 ObjectFactory 延迟决定,只有在真正需要时才创建代理
// 三级缓存存储的是工厂,可以延迟创建代理
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    return exposedObject;
}

Q5: singleton Bean 是线程安全的吗?

回答:不是!

  • Spring Bean 默认是单例,但 Spring 不保证线程安全
  • 如果 Bean 有可变状态,需要自行处理线程安全

解决方案:

// 1. 无状态 Bean(推荐)
@Component
public class StatelessService {
    // 无成员变量,线程安全
    public String process(String input) {
        return input.toUpperCase();
    }
}
 
// 2. 使用 ThreadLocal
@Component
public class StatefulService {
    private ThreadLocal<String> state = new ThreadLocal<>();
}
 
// 3. 改用 prototype 作用域
@Component
@Scope("prototype")
public class PrototypeBean {
    private String state; // 每个线程独立实例
}
 
// 4. 同步控制
@Component
public class SynchronizedService {
    private String state;
    
    public synchronized void setState(String state) {
        this.state = state;
    }
}

总结

Bean 生命周期核心要点:
1. 实例化 → 属性注入 → 初始化 → 使用 → 销毁
2. BeanPostProcessor 在初始化前后介入
3. AOP 代理在初始化后生成
4. 循环依赖通过三级缓存解决
5. 单例 Bean 不保证线程安全