ServletConfigAware 在 Spring 容器中的感知机制源码实现

ServletConfigAware 是 Spring Web 模块中的特殊接口,属于 Spring "感知机制"(Aware Interface) 的核心部分。其底层实现依赖 Spring 容器的生命周期管理和后置处理器机制。以下是关键步骤的源码级拆解:


1. 接口定义
public interface ServletConfigAware {
    void setServletConfig(ServletConfig servletConfig);
}

  • 实现该接口的 Bean 会通过回调方法获取 ServletConfig 对象
  • 属于 Spring 的 Aware 接口族(如 ApplicationContextAware, BeanNameAware

2. 处理入口:ApplicationContextAwareProcessor

org.springframework.context.support.ApplicationContextAwareProcessor 中:

public Object postProcessBeforeInitialization(Object bean, String beanName) {
    if (bean instanceof Aware) {
        // 处理所有Aware接口
        invokeAwareInterfaces(bean);
    }
    return bean;
}

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof ServletConfigAware) {
        ((ServletConfigAware) bean).setServletConfig(this.applicationContext.getServletConfig());
    }
    // 其他Aware接口处理...
}

  • 此处理器在 Bean 初始化被调用(BeanPostProcessor 机制)
  • 通过 applicationContext.getServletConfig() 获取当前环境的 ServletConfig

3. ServletConfig 注入来源

org.springframework.web.context.support.XmlWebApplicationContext

public ServletConfig getServletConfig() {
    return this.servletConfig;
}

  • XmlWebApplicationContext 在初始化时通过 setServletConfig() 接收容器传递的 ServletConfig
  • 数据源头是 Web 容器(如 Tomcat)启动时创建的 ServletConfig

4. 容器启动流程

org.springframework.web.context.ContextLoaderListener

public void contextInitialized(ServletContextEvent event) {
    // 创建WebApplicationContext
    WebApplicationContext context = createWebApplicationContext(event.getServletContext());
    
    // 关键注入:将ServletConfig绑定到上下文
    if (context instanceof ConfigurableWebApplicationContext) {
        ((ConfigurableWebApplicationContext) context).setServletConfig(event.getServletContext());
    }
}

  • Spring 的 ContextLoaderListener 在 Web 容器启动时初始化
  • 通过 setServletConfig()ServletConfig 注入应用上下文

5. **时序流程图解
sequenceDiagram
    participant Web容器 as Tomcat/Jetty
    participant Listener as ContextLoaderListener
    participant Context as XmlWebApplicationContext
    participant Processor as ApplicationContextAwareProcessor
    participant Bean as UserBean
    
    Web容器->>Listener: 启动事件(ServletContextEvent)
    Listener->>Context: 创建应用上下文
    Context->>Context: setServletConfig()
    Context->>Processor: 注册BeanPostProcessor
    Context->>Bean: 实例化Bean
    Processor->>Bean: postProcessBeforeInitialization()
    Bean-->>Processor: 检测到ServletConfigAware
    Processor->>Bean: setServletConfig(config)


6. 设计本质
  1. 控制反转扩展:将容器级对象(ServletConfig)通过接口回调注入 Bean
  2. 生命周期钩子:利用 BeanPostProcessor 在初始化阶段插入自定义逻辑
  3. 解耦设计:Bean 无需主动查找环境对象,实现与容器的低耦合交互

关键源码位置:

  • 接口定义:org.springframework.web.context.ServletConfigAware
  • 处理器:org.springframework.context.support.ApplicationContextAwareProcessor
  • 上下文实现:org.springframework.web.context.support.XmlWebApplicationContext

更多推荐