02. Spring IoC 容器深度解析

2.1 IoC 容器概述

Spring 的 IoC 容器是 Spring Framework 的核心,负责实例化、配置和组装 Bean。容器通过读取配置元数据(XML、注解或 Java 代码)来获取关于要实例化、配置和组装哪些对象的指令。

2.1.1 容器接口层次

BeanFactory (基础容器接口)
    ↑
ListableBeanFactory (可列举 Bean)
    ↑
ConfigurableBeanFactory (可配置)
    ↑
ApplicationContext (应用上下文)
    ↑
ConfigurableApplicationContext (可配置应用上下文)

2.2 BeanFactory 详解

2.2.1 BeanFactory 接口

BeanFactory 是 Spring 容器的根接口,定义了获取 Bean 的基本操作:

public interface BeanFactory {
    // FactoryBean 前缀,用于获取 FactoryBean 本身
    String FACTORY_BEAN_PREFIX = "&";
    
    // 根据名称获取 Bean
    Object getBean(String name) throws BeansException;
    
    // 根据名称和类型获取 Bean
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    
    // 根据类型获取 Bean
    <T> T getBean(Class<T> requiredType) throws BeansException;
    
    // 根据类型获取 ObjectProvider(延迟加载)
    <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
    
    // 判断是否包含指定名称的 Bean
    boolean containsBean(String name);
    
    // 判断是否为单例
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
    // 判断是否为原型
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
    // 获取 Bean 的类型
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    
    // 获取 Bean 的别名
    String[] getAliases(String name);
}

2.2.2 Bean 生命周期

Spring Bean 的完整生命周期如下:

1. 实例化(Instantiation)
   ↓
2. 属性赋值(Populate Properties)
   ↓
3. 设置 BeanName(如果实现了 BeanNameAware)
   ↓
4. 设置 BeanClassLoader(如果实现了 BeanClassLoaderAware)
   ↓
5. 设置 BeanFactory(如果实现了 BeanFactoryAware)
   ↓
6. 设置 Environment(如果实现了 EnvironmentAware)
   ↓
7. 设置 ApplicationContext(如果实现了 ApplicationContextAware)
   ↓
8. BeanPostProcessor.postProcessBeforeInitialization()
   ↓
9. 执行初始化方法(@PostConstruct、InitializingBean.afterPropertiesSet()、自定义 init-method)
   ↓
10. BeanPostProcessor.postProcessAfterInitialization()
   ↓
11. Bean 就绪,可供使用
   ↓
12. 容器关闭
   ↓
13. BeanPostProcessor.postProcessBeforeDestruction()
   ↓
14. 执行销毁方法(@PreDestroy、DisposableBean.destroy()、自定义 destroy-method)

2.2.3 生命周期示例代码

@Component
public class LifecycleBean implements 
        BeanNameAware, 
        BeanFactoryAware, 
        ApplicationContextAware,
        InitializingBean, 
        DisposableBean {
    
    private static final Logger logger = LoggerFactory.getLogger(LifecycleBean.class);
    
    // 1. 构造器
    public LifecycleBean() {
        logger.info("1. Constructor: 实例化");
    }
    
    // 2. 属性赋值
    @Autowired
    public void setDependency(SomeDependency dependency) {
        logger.info("2. Setter: 属性赋值");
    }
    
    // 3. BeanNameAware
    @Override
    public void setBeanName(String name) {
        logger.info("3. BeanNameAware.setBeanName(): {}", name);
    }
    
    // 4. BeanFactoryAware
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        logger.info("4. BeanFactoryAware.setBeanFactory()");
    }
    
    // 5. ApplicationContextAware
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        logger.info("5. ApplicationContextAware.setApplicationContext()");
    }
    
    // 6. @PostConstruct
    @PostConstruct
    public void postConstruct() {
        logger.info("6. @PostConstruct: 初始化前");
    }
    
    // 7. InitializingBean
    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info("7. InitializingBean.afterPropertiesSet()");
    }
    
    // 8. 自定义初始化方法
    public void customInit() {
        logger.info("8. customInit(): 自定义初始化");
    }
    
    // 9. @PreDestroy
    @PreDestroy
    public void preDestroy() {
        logger.info("9. @PreDestroy: 销毁前");
    }
    
    // 10. DisposableBean
    @Override
    public void destroy() throws Exception {
        logger.info("10. DisposableBean.destroy()");
    }
    
    // 11. 自定义销毁方法
    public void customDestroy() {
        logger.info("11. customDestroy(): 自定义销毁");
    }
}

2.3 ApplicationContext 详解

2.3.1 ApplicationContext 功能

ApplicationContext 继承自 BeanFactory,提供了更多企业级功能:

public interface ApplicationContext extends 
        EnvironmentCapable,      // 环境配置能力
        ListableBeanFactory,     // 可列举所有 Bean
        HierarchicalBeanFactory, // 支持父子容器层次
        MessageSource,           // 国际化消息
        ApplicationEventPublisher, // 事件发布
        ResourcePatternResolver {  // 资源加载
    
    String getId();
    String getApplicationName();
    String getDisplayName();
    long getStartupDate();
    ApplicationContext getParent();
    AutowireCapableBeanFactory getAutowireCapableBeanFactory();
}

2.3.2 常用 ApplicationContext 实现

// 1. 注解配置上下文
AnnotationConfigApplicationContext ctx = 
    new AnnotationConfigApplicationContext(AppConfig.class);

// 2. XML 配置上下文
ClassPathXmlApplicationContext xmlCtx = 
    new ClassPathXmlApplicationContext("applicationContext.xml");

// 3. Web 应用上下文
AnnotationConfigWebApplicationContext webCtx = 
    new AnnotationConfigWebApplicationContext();
webCtx.register(WebConfig.class);
webCtx.setServletContext(servletContext);
webCtx.refresh();

2.4 BeanDefinition 详解

2.4.1 BeanDefinition 接口

BeanDefinition 描述了 Bean 的元数据信息:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    // 作用域常量
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
    
    // Bean 角色
    int ROLE_APPLICATION = 0;      // 应用 Bean
    int ROLE_SUPPORT = 1;          // 支持 Bean
    int ROLE_INFRASTRUCTURE = 2;   // 基础设施 Bean
    
    // 可配置属性
    void setParentName(@Nullable String parentName);
    void setBeanClassName(@Nullable String beanClassName);
    void setScope(@Nullable String scope);
    void setLazyInit(boolean lazyInit);
    void setDependsOn(String... dependsOn);
    void setAutowireCandidate(boolean autowireCandidate);
    void setPrimary(boolean primary);
    void setFactoryBeanName(@Nullable String factoryBeanName);
    void setFactoryMethodName(@Nullable String factoryMethodName);
    
    // 获取构造参数和属性值
    ConstructorArgumentValues getConstructorArgumentValues();
    MutablePropertyValues getPropertyValues();
    
    // 初始化/销毁方法
    void setInitMethodName(@Nullable String initMethodName);
    void setDestroyMethodName(@Nullable String destroyMethodName);
}

2.4.2 程序化注册 Bean

@Configuration
public class DynamicBeanConfig {
    
    public static void registerBean(BeanDefinitionRegistry registry) {
        // 创建 BeanDefinition
        RootBeanDefinition beanDefinition = new RootBeanDefinition(MyService.class);
        
        // 设置属性
        beanDefinition.setScope(ConfigurableBeanFactory.SCOPE_SINGLETON);
        beanDefinition.setLazyInit(false);
        beanDefinition.setPrimary(true);
        
        // 添加构造参数
        ConstructorArgumentValues cav = beanDefinition.getConstructorArgumentValues();
        cav.addIndexedArgumentValue(0, "constructorArg1");
        cav.addIndexedArgumentValue(1, 100);
        
        // 添加属性值
        MutablePropertyValues pvs = beanDefinition.getPropertyValues();
        pvs.add("name", "myService");
        pvs.add("enabled", true);
        
        // 注册 Bean
        registry.registerBeanDefinition("myService", beanDefinition);
    }
}

2.5 BeanPostProcessor 扩展点

2.5.1 BeanPostProcessor 接口

BeanPostProcessor 允许在 Bean 初始化前后进行自定义处理:

public interface BeanPostProcessor {
    // 初始化前处理
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) 
            throws BeansException {
        return bean;
    }
    
    // 初始化后处理
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) 
            throws BeansException {
        return bean;
    }
}

2.5.2 自定义 BeanPostProcessor 示例

@Component
public class MetricsBeanPostProcessor implements BeanPostProcessor {
    
    private final Map<String, Class<?>> beanMetrics = new ConcurrentHashMap<>();
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) 
            throws BeansException {
        // 记录 Bean 创建时间
        beanMetrics.put(beanName + "_start", bean.getClass());
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) 
            throws BeansException {
        // 如果是服务层 Bean,添加性能监控代理
        if (bean.getClass().isAnnotationPresent(Service.class)) {
            return createMetricsProxy(bean, beanName);
        }
        return bean;
    }
    
    private Object createMetricsProxy(Object target, String beanName) {
        ProxyFactory proxyFactory = new ProxyFactory(target);
        proxyFactory.addAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                long start = System.currentTimeMillis();
                try {
                    return invocation.proceed();
                } finally {
                    long elapsed = System.currentTimeMillis() - start;
                    System.out.printf("Bean [%s] Method [%s] executed in %dms%n",
                        beanName, invocation.getMethod().getName(), elapsed);
                }
            }
        });
        return proxyFactory.getProxy();
    }
}

2.6 BeanFactoryPostProcessor 扩展点

2.6.1 BeanFactoryPostProcessor 接口

BeanFactoryPostProcessor 在 BeanFactory 标准初始化之后、Bean 实例化之前执行:

@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 
            throws BeansException;
}

2.6.2 自定义 BeanFactoryPostProcessor 示例

@Component
public class DataSourceConfigPostProcessor implements BeanFactoryPostProcessor, 
        EnvironmentAware {
    
    private Environment environment;
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) 
            throws BeansException {
        
        // 动态修改 DataSource BeanDefinition
        BeanDefinition dsBeanDef = beanFactory.getBeanDefinition("dataSource");
        
        // 根据环境设置不同的数据库连接
        String profile = environment.getActiveProfiles()[0];
        if ("dev".equals(profile)) {
            dsBeanDef.getPropertyValues().add("url", "jdbc:h2:mem:testdb");
        } else if ("prod".equals(profile)) {
            dsBeanDef.getPropertyValues().add("url", 
                environment.getProperty("db.prod.url"));
        }
    }
    
    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}

2.7 作用域(Scope)详解

2.7.1 标准作用域

@Configuration
public class ScopeConfig {
    
    // 单例(默认)- 每个 Spring 容器一个实例
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    public SingletonBean singletonBean() {
        return new SingletonBean();
    }
    
    // 原型 - 每次请求创建新实例
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public PrototypeBean prototypeBean() {
        return new PrototypeBean();
    }
}

2.7.2 Web 作用域

@Configuration
public class WebScopeConfig {
    
    // Request 作用域 - 每个 HTTP 请求一个实例
    @Bean
    @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public RequestContext requestContext() {
        return new RequestContext();
    }
    
    // Session 作用域 - 每个 HTTP Session 一个实例
    @Bean
    @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public UserSession userSession() {
        return new UserSession();
    }
    
    // Application 作用域 - 每个 ServletContext 一个实例
    @Bean
    @Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public ApplicationCache applicationCache() {
        return new ApplicationCache();
    }
}

2.8 总结

Spring IoC 容器提供了强大的依赖注入和 Bean 生命周期管理能力:

  1. BeanFactory 是基础容器接口,提供基本的 Bean 获取功能
  2. ApplicationContext 是高级容器,提供企业级功能(国际化、事件、资源加载等)
  3. BeanDefinition 描述 Bean 的元数据信息
  4. BeanPostProcessor 提供 Bean 初始化前后的扩展点
  5. BeanFactoryPostProcessor 提供 BeanFactory 创建后的扩展点
  6. 作用域 控制 Bean 的实例化策略(单例、原型、请求、会话等)

理解这些核心概念是掌握 Spring Framework 的基础。

更多推荐