SpringBoot 扩展容器与请求处理流程源码解析

一、Spring容器核心架构

1.1 BeanFactory 基础结构

Spring容器的核心是BeanFactory接口,它定义了容器的基本行为:

public interface BeanFactory {// 通过名称获取BeanObject getBean(String name) throws BeansException;// 通过类型获取Bean<T> T getBean(Class<T> requiredType) throws BeansException;// 判断是否包含指定名称的Beanboolean containsBean(String name);// 判断Bean是否为单例boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 获取Bean的类型Class<?> getType(String name) throws NoSuchBeanDefinitionException;// 获取Bean的别名String[] getAliases(String name);// 工厂Bean的前缀String FACTORY_BEAN_PREFIX = "&";
}

BeanFactory提供了最基本的Bean查找和管理功能,它有多种实现,如XmlBeanFactoryDefaultListableBeanFactory等。

1.2 ApplicationContext 扩展

ApplicationContextBeanFactory的子接口,它扩展了更多功能:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {// 返回容器的唯一IDString getId();// 返回容器的显示名称String getDisplayName();// 返回容器的启动时间long getStartupDate();// 返回父容器ApplicationContext getParent();// 返回AutowireCapableBeanFactoryAutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

ApplicationContext提供了国际化支持、资源加载、事件发布等高级功能,是Spring应用中最常用的容器接口。

1.3 容器初始化流程

Spring容器的初始化过程主要包括:

  1. Resource定位:通过ResourceLoader加载配置资源
  2. BeanDefinition加载:解析配置资源,生成BeanDefinition
  3. BeanDefinition注册:将BeanDefinition注册到BeanDefinitionRegistry
  4. Bean创建:在需要时创建和初始化Bean

核心源码流程如下:

public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext {// 容器刷新方法@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 准备刷新环境prepareRefresh();// 获取BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 准备BeanFactoryprepareBeanFactory(beanFactory);try {// 允许子类对BeanFactory进行后处理postProcessBeanFactory(beanFactory);// 调用BeanFactoryPostProcessorinvokeBeanFactoryPostProcessors(beanFactory);// 注册BeanPostProcessorregisterBeanPostProcessors(beanFactory);// 初始化消息源initMessageSource();// 初始化事件广播器initApplicationEventMulticaster();// 特定子类的初始化onRefresh();// 注册监听器registerListeners();// 实例化所有剩余的非懒加载单例BeanfinishBeanFactoryInitialization(beanFactory);// 完成刷新,发布事件finishRefresh();}catch (BeansException ex) {// 异常处理destroyBeans();cancelRefresh(ex);throw ex;}finally {// 重置公共缓存resetCommonCaches();}}}// 其他方法...
}

二、SpringBoot自动配置原理

2.1 自动配置基础

SpringBoot的自动配置是基于@EnableAutoConfiguration注解实现的:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {// 排除不需要的自动配置类Class<?>[] exclude() default {};// 排除不需要的自动配置类名String[] excludeName() default {};
}

@EnableAutoConfiguration通过@Import注解导入AutoConfigurationImportSelector,该选择器负责加载自动配置类。

2.2 自动配置加载流程

自动配置类的加载主要通过以下步骤完成:

  1. 读取配置文件:从META-INF/spring.factories文件中读取所有自动配置类
  2. 过滤配置类:根据条件注解(如@ConditionalOnClass@ConditionalOnMissingBean等)过滤不需要的配置类
  3. 排序配置类:根据@AutoConfigureOrder@AutoConfigureBefore@AutoConfigureAfter注解排序配置类
  4. 加载配置类:将符合条件的配置类注册到容器中

核心源码如下:

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}// 加载自动配置元数据AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);// 获取自动配置类AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}// 获取注解属性AnnotationAttributes attributes = getAttributes(annotationMetadata);// 获取候选配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);// 移除重复项configurations = removeDuplicates(configurations);// 获取需要排除的配置类Set<String> exclusions = getExclusions(annotationMetadata, attributes);// 检查排除项checkExcludedClasses(configurations, exclusions);// 移除需要排除的配置类configurations.removeAll(exclusions);// 根据条件过滤配置类configurations = filter(configurations, autoConfigurationMetadata);// 发布自动配置导入事件fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);}// 其他方法...
}

2.3 条件注解机制

SpringBoot的自动配置依赖于条件注解,常见的条件注解包括:

  • @ConditionalOnClass:当类路径下存在指定类时生效
  • @ConditionalOnMissingClass:当类路径下不存在指定类时生效
  • @ConditionalOnBean:当容器中存在指定Bean时生效
  • @ConditionalOnMissingBean:当容器中不存在指定Bean时生效
  • @ConditionalOnProperty:当配置属性存在且满足指定条件时生效
  • @ConditionalOnResource:当类路径下存在指定资源时生效
  • @ConditionalOnWebApplication:当应用是Web应用时生效
  • @ConditionalOnNotWebApplication:当应用不是Web应用时生效

这些条件注解的实现基于Condition接口:

public interface Condition {// 判断条件是否满足boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

三、SpringMVC请求处理流程

3.1 DispatcherServlet 核心作用

DispatcherServlet是SpringMVC的核心前端控制器,负责接收所有HTTP请求并协调处理流程:

public class DispatcherServlet extends FrameworkServlet {// 主要处理方法@Overrideprotected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {logRequest(request);// 保存原请求属性Map<String, Object> attributesSnapshot = null;if (WebUtils.isIncludeRequest(request)) {attributesSnapshot = new HashMap<>();Enumeration<?> attrNames = request.getAttributeNames();while (attrNames.hasMoreElements()) {String attrName = (String) attrNames.nextElement();if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {attributesSnapshot.put(attrName, request.getAttribute(attrName));}}}// 设置请求属性request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());if (this.flashMapManager != null) {FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);if (inputFlashMap != null) {request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));}request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);}try {// 执行请求处理doDispatch(request, response);}finally {if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {// 恢复原请求属性if (attributesSnapshot != null) {restoreAttributesAfterInclude(request, attributesSnapshot);}}}}// 其他方法...
}

3.2 请求处理流程详解

SpringMVC的请求处理流程主要包括:

  1. 请求映射:根据请求URL找到对应的Handler
  2. HandlerAdapter调用:通过HandlerAdapter调用Handler
  3. Handler执行:执行具体的业务逻辑
  4. ModelAndView返回:Handler返回ModelAndView
  5. 视图解析:通过ViewResolver解析视图名称
  6. 视图渲染:将Model数据渲染到View中

核心源码流程如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {// 检查是否是文件上传请求processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);// 确定HandlermappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// 确定HandlerAdapterHandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// 处理Last-Modified请求头String method = request.getMethod();boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}// 应用前置拦截器if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 调用Handlermv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}// 设置默认视图applyDefaultViewName(processedRequest, mv);// 应用后置拦截器mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {// 处理错误dispatchException = new NestedServletException("Handler dispatch failed", err);}// 处理结果processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {// 触发拦截器的afterCompletion方法triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {// 触发拦截器的afterCompletion方法triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {// 处理异步请求if (asyncManager.isConcurrentHandlingStarted()) {// 应用拦截器的afterConcurrentHandlingStarted方法if (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// 清理多部分请求if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}}
}

3.3 HandlerMapping 与 HandlerAdapter

HandlerMapping负责将请求映射到Handler:

public interface HandlerMapping {// 根据请求获取Handler执行链HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

常见的HandlerMapping实现包括:

  • RequestMappingHandlerMapping:处理@RequestMapping注解的Handler
  • BeanNameUrlHandlerMapping:根据Bean名称映射URL
  • SimpleUrlHandlerMapping:简单的URL到Handler映射

HandlerAdapter负责调用Handler:

public interface HandlerAdapter {// 判断是否支持该Handlerboolean supports(Object handler);// 处理请求ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;// 获取Last-Modified时间long getLastModified(HttpServletRequest request, Object handler);
}

常见的HandlerAdapter实现包括:

  • RequestMappingHandlerAdapter:处理@RequestMapping注解的Handler
  • SimpleControllerHandlerAdapter:处理Controller接口的Handler
  • HttpRequestHandlerAdapter:处理HttpRequestHandler接口的Handler

四、扩展Spring容器

4.1 BeanFactoryPostProcessor 扩展

BeanFactoryPostProcessor允许在BeanDefinition加载后但Bean实例化前修改BeanDefinition:

public interface BeanFactoryPostProcessor {// 对BeanFactory进行后处理void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

实现示例:

@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// 获取所有BeanDefinition名称String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();for (String beanName : beanDefinitionNames) {BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);// 修改BeanDefinition属性if ("myBean".equals(beanName)) {beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);}}}
}

4.2 BeanPostProcessor 扩展

BeanPostProcessor允许在Bean实例化后但初始化前后进行处理:

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

实现示例:

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// 在Bean初始化前执行if (bean instanceof MyService) {System.out.println("Before initializing MyService");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// 在Bean初始化后执行if (bean instanceof MyService) {System.out.println("After initializing MyService");}return bean;}
}

4.3 FactoryBean 扩展

FactoryBean允许创建复杂的Bean实例:

public interface FactoryBean<T> {// 返回Bean实例T getObject() throws Exception;// 返回Bean类型Class<?> getObjectType();// 是否单例default boolean isSingleton() {return true;}
}

实现示例:

@Component
public class MyFactoryBean implements FactoryBean<MyService> {@Overridepublic MyService getObject() throws Exception {// 创建复杂的Bean实例MyServiceImpl service = new MyServiceImpl();service.setConfig(new Config("customConfig"));return service;}@Overridepublic Class<?> getObjectType() {return MyService.class;}@Overridepublic boolean isSingleton() {return true;}
}

4.4 自定义注解扩展

可以通过自定义注解扩展Spring容器功能:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CustomImportSelector.class)
public @interface EnableCustomFeature {// 注解属性String value() default "";
}

自定义导入选择器:

public class CustomImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// 根据条件选择要导入的配置类Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes(EnableCustomFeature.class.getName());String value = (String) attributes.get("value");if ("advanced".equals(value)) {return new String[] { "com.example.config.AdvancedConfig" };} else {return new String[] { "com.example.config.BasicConfig" };}}
}

五、扩展SpringMVC请求处理流程

5.1 自定义 HandlerInterceptor

HandlerInterceptor允许在请求处理前后添加自定义逻辑:

public interface HandlerInterceptor {// 请求处理前调用default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return true;}// 请求处理后但视图渲染前调用default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable ModelAndView modelAndView) throws Exception {}// 整个请求完成后调用default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable Exception ex) throws Exception {}
}

实现示例:

@Component
public class CustomInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 请求处理前逻辑System.out.println("Pre-handling request: " + request.getRequestURI());return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 请求处理后逻辑System.out.println("Post-handling request: " + request.getRequestURI());}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完成后逻辑System.out.println("Request completed: " + request.getRequestURI());}
}

注册拦截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CustomInterceptor customInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(customInterceptor).addPathPatterns("/**").excludePathPatterns("/static/**");}
}

5.2 自定义 Converter 和 Formatter

Converter用于类型转换:

public interface Converter<S, T> {// 转换方法T convert(S source);
}

实现示例:

@Component
public class StringToDateConverter implements Converter<String, Date> {private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");@Overridepublic Date convert(String source) {try {return dateFormat.parse(source);} catch (ParseException e) {throw new IllegalArgumentException("Invalid date format", e);}}
}

Formatter用于格式化和解析:

public interface Formatter<T> extends Printer<T>, Parser<T> {
}

实现示例:

@Component
public class DateFormatter implements Formatter<Date> {private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");@Overridepublic String print(Date object, Locale locale) {return dateFormat.format(object);}@Overridepublic Date parse(String text, Locale locale) throws ParseException {return dateFormat.parse(text);}
}

注册转换器和格式化器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverter(new StringToDateConverter());registry.addFormatter(new DateFormatter());}
}

5.3 自定义 ArgumentResolver

HandlerMethodArgumentResolver允许自定义方法参数解析:

public interface HandlerMethodArgumentResolver {// 判断是否支持该参数boolean supportsParameter(MethodParameter parameter);// 解析参数值Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}

实现示例:

@Component
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.hasParameterAnnotation(CurrentUser.class);}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {// 从Session或Token中获取当前用户HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);User user = (User) request.getSession().getAttribute("currentUser");if (user == null) {throw new AuthenticationException("User not authenticated");}return user;}
}

注册参数解析器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CurrentUserArgumentResolver currentUserArgumentResolver;@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(currentUserArgumentResolver);}
}

5.4 自定义 ReturnValueHandler

HandlerMethodReturnValueHandler允许自定义返回值处理:

public interface HandlerMethodReturnValueHandler {// 判断是否支持该返回值类型boolean supportsReturnType(MethodParameter returnType);// 处理返回值void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}

实现示例:

@Component
public class CustomReturnValueHandler implements HandlerMethodReturnValueHandler {@Overridepublic boolean supportsReturnType(MethodParameter returnType) {return returnType.getParameterType().equals(ApiResponse.class);}@Overridepublic void handleReturnValue(Object returnValue, MethodParameter returnType,ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {// 设置响应状态HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);ApiResponse apiResponse = (ApiResponse) returnValue;response.setStatus(apiResponse.getStatus());// 写入响应内容ObjectMapper objectMapper = new ObjectMapper();response.setContentType(MediaType.APPLICATION_JSON_VALUE);response.getWriter().write(objectMapper.writeValueAsString(apiResponse));// 标记请求已处理mavContainer.setRequestHandled(true);}
}

注册返回值处理器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CustomReturnValueHandler customReturnValueHandler;@Overridepublic void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {handlers.add(customReturnValueHandler);}
}

六、异步请求处理

6.1 异步请求基础

SpringMVC支持多种异步请求处理方式:

  1. Callable:返回一个Callable对象,在另一个线程中执行
  2. DeferredResult:允许在另一个线程中设置返回结果
  3. WebAsyncTask:类似于Callable,但提供更多控制选项
  4. Reactive类型:如Mono和Flux,用于响应式编程

6.2 Callable 异步处理

@GetMapping("/async/callable")
public Callable<String> asyncCallable() {return () -> {// 执行耗时操作Thread.sleep(2000);return "Async response";};
}

核心处理逻辑:

// DispatcherServlet中处理Callable的代码
if (value instanceof Callable) {Callable<?> callable = (Callable<?>) value;WebAsyncUtils.getAsyncManager(request).startCallableProcessing(callable, mavContainer);return;
}

6.3 DeferredResult 异步处理

@GetMapping("/async/deferred")
public DeferredResult<String> asyncDeferredResult() {DeferredResult<String> deferredResult = new DeferredResult<>(5000L);// 模拟异步处理CompletableFuture.runAsync(() -> {try {Thread.sleep(2000);deferredResult.setResult("Async response");} catch (Exception e) {deferredResult.setErrorResult(e);}});return deferredResult;
}

核心处理逻辑:

// DispatcherServlet中处理DeferredResult的代码
if (value instanceof DeferredResult) {DeferredResult<?> deferredResult = (DeferredResult<?>) value;WebAsyncUtils.getAsyncManager(request).startDeferredResultProcessing(deferredResult, mavContainer);return;
}

6.4 异步请求流程

异步请求的核心流程:

  1. 主线程接收请求并返回一个异步结果(Callable/DeferredResult等)
  2. DispatcherServlet释放当前线程,允许其处理其他请求
  3. 异步任务在另一个线程中执行
  4. 异步任务完成后,通过AsyncWebRequest通知容器
  5. 容器重新分派请求,处理结果并返回响应

关键类和接口:

  • WebAsyncManager:管理异步请求
  • AsyncWebRequest:异步请求接口
  • DeferredResultProcessingInterceptor:DeferredResult处理拦截器
  • CallableProcessingInterceptor:Callable处理拦截器

七、异常处理机制

7.1 异常处理基础

SpringMVC提供了多种异常处理方式:

  1. @ExceptionHandler:处理控制器内的异常
  2. @ControllerAdvice + @ExceptionHandler:全局异常处理
  3. HandlerExceptionResolver:自定义异常解析器
  4. ResponseStatusException:直接返回特定状态码的异常

7.2 @ExceptionHandler 注解

@Controller
public class UserController {@GetMapping("/users/{id}")public User getUser(@PathVariable Long id) {// 业务逻辑throw new UserNotFoundException("User not found with id: " + id);}@ExceptionHandler(UserNotFoundException.class)public ResponseEntity<String> handleUserNotFoundException(UserNotFoundException ex) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());}
}

7.3 @ControllerAdvice 全局异常处理

@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) {ErrorResponse response = new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(),"Internal Server Error",ex.getMessage());return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);}@ExceptionHandler(IllegalArgumentException.class)public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex) {ErrorResponse response = new ErrorResponse(HttpStatus.BAD_REQUEST.value(),"Bad Request",ex.getMessage());return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);}
}

7.4 HandlerExceptionResolver 接口

public interface HandlerExceptionResolver {// 解析异常并返回ModelAndView@NullableModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);
}

自定义实现示例:

@Component
public class CustomExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {if (ex instanceof CustomException) {try {response.sendError(HttpStatus.CONFLICT.value(), ex.getMessage());} catch (IOException e) {e.printStackTrace();}return new ModelAndView();}return null;}
}

7.5 异常处理流程

异常处理的核心流程:

  1. 当请求处理过程中抛出异常时,DispatcherServlet捕获异常
  2. DispatcherServlet遍历所有注册的HandlerExceptionResolver
  3. 第一个能够处理该异常的Resolver返回ModelAndView
  4. DispatcherServlet使用返回的ModelAndView进行视图渲染
  5. 如果没有Resolver能够处理该异常,将返回默认错误响应

核心源码:

// DispatcherServlet中处理异常的代码
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,@Nullable Exception exception) throws Exception {boolean errorView = false;if (exception != null) {if (exception instanceof ModelAndViewDefiningException) {logger.debug("ModelAndViewDefiningException encountered", exception);mv = ((ModelAndViewDefiningException) exception).getModelAndView();}else {Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);mv = processHandlerException(request, response, handler, exception);errorView = (mv != null);}}// 其他处理...
}// 处理异常的方法
@Nullable
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,@Nullable Object handler, Exception ex) throws Exception {// 标记为异步处理失败WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);if (asyncManager.isConcurrentHandlingStarted()) {if (logger.isErrorEnabled()) {logger.error("Async handler error for request [" + getRequestUri(request) + "]: " + ex.getMessage());}asyncManager.setConcurrentHandlingFailed(ex);return null;}// 保存原始异常request.setAttribute(EXCEPTION_ATTRIBUTE, ex);// 尝试使用HandlerExceptionResolvers处理异常ModelAndView exMv = null;if (this.handlerExceptionResolvers != null) {for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {exMv = resolver.resolveException(request, response, handler, ex);if (exMv != null) {break;}}}// 其他处理...return exMv;
}

八、拦截器与过滤器

8.1 过滤器(Filter)基础

过滤器是Servlet规范的一部分,用于在请求到达Servlet之前或响应返回客户端之前进行预处理或后处理:

public interface Filter {// 初始化过滤器default void init(FilterConfig filterConfig) throws ServletException {}// 过滤请求void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException;// 销毁过滤器default void destroy() {}
}

8.2 拦截器(Interceptor)基础

拦截器是SpringMVC框架的一部分,用于在请求处理前后添加自定义逻辑:

public interface HandlerInterceptor {// 请求处理前调用default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {return true;}// 请求处理后但视图渲染前调用default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable ModelAndView modelAndView) throws Exception {}// 整个请求完成后调用default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,@Nullable Exception ex) throws Exception {}
}

8.3 过滤器与拦截器的区别

特性

过滤器(Filter)

拦截器(Interceptor)

规范

Servlet规范

SpringMVC框架

应用范围

所有请求

仅SpringMVC处理的请求

执行顺序

在Servlet之前

在HandlerMapping之后

访问Handler

不能

可以

访问ModelAndView

不能

可以

异常处理

不能捕获Handler中的异常

可以捕获Handler中的异常

依赖注入

不支持

支持

8.4 过滤器链与拦截器链

过滤器链的执行流程:

  1. 客户端请求到达Servlet容器
  2. 容器按照注册顺序调用所有匹配的过滤器
  3. 最后一个过滤器调用目标Servlet
  4. 目标Servlet处理请求
  5. 响应返回时,过滤器按照相反顺序执行后处理逻辑

拦截器链的执行流程:

  1. DispatcherServlet接收请求
  2. HandlerMapping确定Handler和Interceptor链
  3. 按照注册顺序调用所有Interceptor的preHandle方法
  4. 调用Handler处理请求
  5. 按照相反顺序调用所有Interceptor的postHandle方法
  6. 视图渲染
  7. 按照相反顺序调用所有Interceptor的afterCompletion方法

8.5 自定义过滤器与拦截器

自定义过滤器示例:

@Component
public class CustomFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 请求预处理HttpServletRequest httpRequest = (HttpServletRequest) request;System.out.println("Filter: Pre-processing request for " + httpRequest.getRequestURI());// 继续过滤器链chain.doFilter(request, response);// 响应后处理System.out.println("Filter: Post-processing response for " + httpRequest.getRequestURI());}
}

注册过滤器:

@Configuration
public class WebConfig {@Autowiredprivate CustomFilter customFilter;@Beanpublic FilterRegistrationBean<CustomFilter> customFilterRegistration() {FilterRegistrationBean<CustomFilter> registration = new FilterRegistrationBean<>();registration.setFilter(customFilter);registration.addUrlPatterns("/*");registration.setName("customFilter");registration.setOrder(1);return registration;}
}

自定义拦截器示例:

@Component
public class CustomInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 请求处理前逻辑System.out.println("Interceptor: Pre-handling request for " + request.getRequestURI());return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 请求处理后逻辑System.out.println("Interceptor: Post-handling request for " + request.getRequestURI());}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完成后逻辑System.out.println("Interceptor: Request completed for " + request.getRequestURI());}
}

注册拦截器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate CustomInterceptor customInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(customInterceptor).addPathPatterns("/**").excludePathPatterns("/static/**");}
}

九、内容协商机制

9.1 内容协商基础

内容协商是指根据客户端的请求头(如Accept)决定返回的响应格式。SpringMVC提供了灵活的内容协商机制,支持多种方式确定响应格式:

  1. 基于请求头的内容协商:根据客户端的Accept头选择合适的响应格式
  2. 基于URL扩展名的内容协商:通过URL中的扩展名(如.json、.xml)决定响应格式
  3. 基于请求参数的内容协商:通过请求参数(如?format=json)决定响应格式

9.2 内容协商配置

配置内容协商:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {configurer// 启用基于URL扩展名的内容协商.favorPathExtension(true)// 启用基于请求参数的内容协商.favorParameter(true)// 请求参数名.parameterName("format")// 默认内容类型.defaultContentType(MediaType.APPLICATION_JSON)// 媒体类型映射.mediaType("json", MediaType.APPLICATION_JSON).mediaType("xml", MediaType.APPLICATION_XML);}
}

9.3 内容协商流程

内容协商的核心流程:

  1. DispatcherServlet接收到请求后,根据配置的内容协商策略确定请求期望的媒体类型
  2. Handler处理请求并返回ModelAndView
  3. DispatcherServlet根据确定的媒体类型选择合适的ViewResolver
  4. ViewResolver解析视图并返回View
  5. View将Model数据渲染为指定格式的响应

关键类和接口:

  • ContentNegotiationManager:内容协商管理器
  • ContentNegotiationStrategy:内容协商策略接口
  • PathExtensionContentNegotiationStrategy:基于路径扩展名的协商策略
  • ParameterContentNegotiationStrategy:基于请求参数的协商策略
  • HeaderContentNegotiationStrategy:基于请求头的协商策略

9.4 自定义内容协商策略

自定义内容协商策略:

public class CustomContentNegotiationStrategy implements ContentNegotiationStrategy {@Overridepublic List<MediaType> resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException {// 从请求中获取自定义的内容类型参数String format = request.getParameter("responseFormat");if (StringUtils.hasText(format)) {switch (format.toLowerCase()) {case "json":return Collections.singletonList(MediaType.APPLICATION_JSON);case "xml":return Collections.singletonList(MediaType.APPLICATION_XML);case "csv":return Collections.singletonList(MediaType.valueOf("text/csv"));}}// 返回默认媒体类型列表return MEDIA_TYPE_ALL_LIST;}
}

注册自定义策略:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {configurer.strategies(strategies -> {// 添加自定义策略strategies.add(0, new CustomContentNegotiationStrategy());});}
}

十、请求参数绑定与数据转换

10.1 请求参数绑定基础

SpringMVC提供了强大的请求参数绑定机制,能够将HTTP请求中的各种参数(如URL参数、表单参数、JSON数据等)绑定到方法参数上。

常用的参数绑定注解:

  • @PathVariable:绑定URL路径变量
  • @RequestParam:绑定URL查询参数
  • @RequestBody:绑定请求体
  • @RequestHeader:绑定请求头
  • @CookieValue:绑定Cookie值
  • @ModelAttribute:绑定表单数据或命令对象

10.2 数据转换机制

SpringMVC的数据转换机制基于以下核心接口:

  1. Converter:简单的类型转换器
  2. ConverterFactory:创建一组相关的转换器
  3. GenericConverter:支持更复杂的类型转换
  4. Formatter:格式化器,支持文本与对象之间的双向转换
  5. ConversionService:转换服务,管理所有转换器和格式化器

10.3 自定义转换器

自定义转换器示例:

@Component
public class StringToLocalDateConverter implements Converter<String, LocalDate> {private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");@Overridepublic LocalDate convert(String source) {if (source == null || source.isEmpty()) {return null;}return LocalDate.parse(source, formatter);}
}

注册转换器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverter(new StringToLocalDateConverter());}
}

10.4 自定义格式化器

自定义格式化器示例:

@Component
public class LocalDateTimeFormatter implements Formatter<LocalDateTime> {private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");@Overridepublic String print(LocalDateTime object, Locale locale) {return object.format(formatter);}@Overridepublic LocalDateTime parse(String text, Locale locale) throws ParseException {return LocalDateTime.parse(text, formatter);}
}

十一、请求处理中的数据验证

11.1 验证框架基础

SpringMVC 整合了 Hibernate Validator 作为默认的数据验证框架,遵循 JSR-303(Bean Validation 1.0)和 JSR-349(Bean Validation 1.1)规范。验证功能基于注解驱动,通过在实体类属性、方法参数等位置添加验证注解,实现对输入数据的合法性校验。

核心验证注解包括:

  • @NotNull:验证对象不为空
  • @NotEmpty:验证字符串不为空且长度大于 0,集合、数组等不为空
  • @NotBlank:验证字符串不为空,去除首尾空格后长度大于 0
  • @Size:验证字符串长度、集合大小、数组长度等在指定范围内
  • @Min@Max:验证数值类型在指定的最小值和最大值范围内
  • @Pattern:验证字符串匹配指定的正则表达式
  • @Email:验证字符串是否为合法的邮箱格式

11.2 验证流程解析

当请求到达控制器方法时,若方法参数标注了验证相关注解(如 @Valid@Validated),SpringMVC 会启动验证流程。

  1. 验证器获取:Spring 容器中会自动装配 LocalValidatorFactoryBean,它实现了 Validator 接口,是默认的验证器。LocalValidatorFactoryBean 会根据配置加载验证规则,如从属性文件中读取自定义错误信息。
public class LocalValidatorFactoryBean extends SpringValidatorAdapter implements FactoryBean<Validator>, InitializingBean {// 省略部分代码@Overridepublic Validator getObject() throws Exception {return this;}// 初始化时设置参数解析器等@Overridepublic void afterPropertiesSet() throws Exception {setMessageInterpolator(new ResourceBundleMessageInterpolator(getMessageInterpolatorArguments()));setConstraintValidatorFactory(new SpringConstraintValidatorFactory(getBeanFactory()));super.afterPropertiesSet();}
}
  1. 验证执行:以方法参数验证为例,当方法参数标注 @Valid 时,HandlerMethodArgumentResolver 中的 ServletRequestMethodArgumentResolver 会触发验证。在解析参数过程中,会调用 Validatorvalidate 方法对对象进行验证。
// ServletRequestMethodArgumentResolver 部分代码
protected Object resolveCommonArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {// 省略部分代码if (parameter.hasParameterAnnotation(Valid.class) || parameter.hasParameterAnnotation(Validated.class)) {binder.validate(argument);if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());}}return argument;
}
  1. 错误处理:如果验证失败,会将错误信息封装到 BindingResult 中。若未对错误进行处理,默认会抛出 MethodArgumentNotValidExceptionBindException。开发者可以通过 @ExceptionHandler 注解在控制器内捕获该异常,也可以使用 @ControllerAdvice 进行全局异常处理,将错误信息以合适的格式返回给客户端。

11.3 自定义验证注解

开发者可以通过实现 ConstraintConstraintValidator 接口来自定义验证注解。

  1. 定义自定义验证注解
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CustomValidator.class)
@Documented
public @interface CustomValidation {String message() default "{custom.validation.error}";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
  1. 实现自定义验证器
public class CustomValidator implements ConstraintValidator<CustomValidation, String> {private int minLength;private int maxLength;@Overridepublic void initialize(CustomValidation constraintAnnotation) {minLength = constraintAnnotation.minLength();maxLength = constraintAnnotation.maxLength();}@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if (value == null) {return false;}int length = value.length();return length >= minLength && length <= maxLength;}
}

在使用时,将自定义注解标注在需要验证的属性或参数上,即可触发自定义的验证逻辑。

十二、Spring容器的事件机制

12.1 事件模型概述

Spring 容器提供了一套事件发布和监听机制,允许应用程序在特定事件发生时执行相应的逻辑。事件机制基于观察者模式,主要涉及三个核心组件:事件(ApplicationEvent)、事件发布者(ApplicationEventPublisher)和事件监听器(ApplicationListener)。

12.2 核心接口与类解析

  1. ApplicationEvent:所有 Spring 事件的基类,继承自 java.util.EventObject。开发者可以通过继承该类自定义事件。
public abstract class ApplicationEvent extends EventObject {private static final long serialVersionUID = 7099057708183571937L;public ApplicationEvent(Object source) {super(source);}
}
  1. ApplicationEventPublisher:事件发布接口,ApplicationContext 继承了该接口,因此所有的 ApplicationContext 实例都可以作为事件发布者。AbstractApplicationContext 中通过 this.applicationEventPublisher = this; 将自身赋值为事件发布者。
public interface ApplicationEventPublisher {void publishEvent(ApplicationEvent event);void publishEvent(Object event);
}
  1. ApplicationListener:事件监听器接口,实现该接口的类可以监听特定类型的事件。
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {void onApplicationEvent(E event);
}

12.3 事件发布与监听流程

  1. 事件发布:当需要发布事件时,调用 ApplicationEventPublisherpublishEvent 方法。例如在 AbstractApplicationContextfinishRefresh 方法中,会发布 ContextRefreshedEvent 事件,表示容器刷新完成。
protected void finishRefresh() {// 省略部分代码publishEvent(new ContextRefreshedEvent(this));// 省略部分代码
}
  1. 事件监听:Spring 容器在启动过程中,会扫描容器中所有实现了 ApplicationListener 接口的 Bean,并将其注册到事件多播器(ApplicationEventMulticaster)中。默认的事件多播器是 SimpleApplicationEventMulticaster。当事件发布时,SimpleApplicationEventMulticaster 会遍历所有注册的监听器,判断监听器是否支持该事件类型,若支持则调用监听器的 onApplicationEvent 方法处理事件。
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {@Overridepublic void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {Executor executor = getTaskExecutor();if (executor != null) {executor.execute(() -> invokeListener(listener, event));} else {invokeListener(listener, event);}}}// 省略部分代码
}

12.4 自定义事件与监听器

  1. 自定义事件:继承 ApplicationEvent 类创建自定义事件。
public class CustomEvent extends ApplicationEvent {private String message;public CustomEvent(Object source, String message) {super(source);this.message = message;}public String getMessage() {return message;}
}
  1. 自定义监听器:实现 ApplicationListener 接口,监听自定义事件。
@Component
public class CustomEventListener implements ApplicationListener<CustomEvent> {@Overridepublic void onApplicationEvent(CustomEvent event) {System.out.println("Received custom event: " + event.getMessage());}
}

在应用中合适的地方发布自定义事件,即可触发自定义监听器的逻辑。

十三、SpringBoot 应用的启动流程

13.1 启动入口解析

SpringBoot 应用的启动入口是包含 @SpringBootApplication 注解的主类,该注解是一个组合注解,包含了 @EnableAutoConfiguration@ComponentScan@Configuration 等核心注解。以常见的启动类为例:

@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

13.2 SpringApplication 启动核心流程

  1. 创建 SpringApplication 实例:在 SpringApplication.run 方法中,首先会根据传入的主类等信息创建 SpringApplication 实例。在创建过程中,会判断应用类型(如是否为 Web 应用),加载应用的监听器、初始化器等。
public class SpringApplication {public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();}// 省略部分代码
}
  1. 启动应用:调用 SpringApplicationrun 方法启动应用。该方法会完成一系列关键操作:
  • 记录启动时间,创建并配置 ConfigurableApplicationContext 上下文实例(默认为 AnnotationConfigServletWebServerApplicationContext 等类型,根据应用类型而定)。
  • 配置应用环境,包括加载配置文件、解析命令行参数等。
  • 发布 ApplicationStartingEvent 事件,表示应用开始启动。
  • 刷新上下文,这是容器初始化的核心步骤,会执行如加载 BeanDefinition、实例化 Bean 等操作。
  • 发布 ApplicationReadyEvent 事件,表示应用已准备就绪。
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();exceptionReporters = getSpringBootExceptionReporters(context);prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;
}

13.3 启动过程中的扩展点

  1. ApplicationRunnerCommandLineRunner:实现这两个接口的 Bean 会在应用启动完成后执行,ApplicationRunnerrun 方法接收 ApplicationArguments 参数,CommandLineRunnerrun 方法接收字符串数组参数,方便在启动后执行一些初始化任务。
@Component
public class MyApplicationRunner implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("ApplicationRunner is running...");}
}@Component
public class MyCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("CommandLineRunner is running...");}
}
  1. ApplicationContextInitializer:在 SpringApplication 创建过程中会加载实现该接口的类,其 initialize 方法会在 ConfigurableApplicationContext 刷新前执行,可以用于对应用上下文进行提前配置。
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {void initialize(C applicationContext);
}

十四、Spring容器的 Bean 作用域与生命周期

14.1 Bean 作用域详解

Spring 容器支持多种 Bean 作用域,通过 @Scope 注解指定,不同作用域决定了 Bean 的创建和管理方式。

  1. singleton:单例作用域,默认作用域。在整个应用生命周期内,容器中只会存在一个该 Bean 的实例,所有对该 Bean 的请求都会返回同一个实例。容器在初始化时创建单例 Bean。
@Service
@Scope("singleton")
public class SingletonService {// 省略代码
}
  1. prototype:原型作用域。每次请求获取该 Bean 时,容器都会创建一个新的实例。适用于轻量级、无状态的 Bean。
@Service
@Scope("prototype")
public class PrototypeService {// 省略代码
}
  1. request:请求作用域。在一次 HTTP 请求中,容器中只会存在一个该 Bean 的实例,不同请求会创建不同实例。仅适用于 Web 应用。
@Service
@Scope("request")
public class RequestScopedService {// 省略代码
}
  1. session:会话作用域。在一个 HTTP 会话中,容器中只会存在一个该 Bean 的实例,不同会话会创建不同实例。仅适用于 Web 应用。
@Service
@Scope("session")
public class SessionScopedService {// 省略代码
}
  1. application:应用作用域(相当于 ServletContext 作用域)。在整个 Web 应用中,容器中只会存在一个该 Bean 的实例。仅适用于 Web 应用。

14.2 Bean 生命周期流程

  1. 实例化:容器根据 BeanDefinition 创建 Bean 实例,通过反射调用构造函数完成对象创建。如果 Bean 有多个构造函数,Spring 会通过一定的策略选择合适的构造函数,如首选带有 @Autowired 注解的构造函数。
  2. 依赖注入:使用 @Autowired@Value 等注解完成属性注入或方法注入,为 Bean 设置依赖关系。依赖注入由 AutowiredAnnotationBeanPostProcessor 等后置处理器完成。
  3. 初始化前处理:如果 Bean 实现了 BeanNameAwareBeanFactoryAwareApplicationContextAware 等接口,容器会在此时调用相应的 setBeanNamesetBeanFactorysetApplicationContext 方法,将相关资源注入到 Bean 中。
  4. 初始化方法调用:如果 Bean 配置了初始化方法(通过 @PostConstruct 注解或 init-method 属性指定),容器会调用该方法,进行一些初始化操作。
  5. 就绪状态:Bean 进入就绪状态,可以被应用程序使用。
  6. 销毁前处理:当容器关闭时,如果 Bean 实现了 DisposableBean 接口,或配置了销毁方法(通过 @PreDestroy 注解或 destroy-method 属性指定),容器会调用相应的 destroy 方法或销毁方法,进行资源清理等操作。

14.3 后置处理器对生命周期的影响

  1. BeanPostProcessor:实现该接口的后置处理器可以在 Bean 初始化前后对 Bean 进行处理。例如 ApplicationContextAwareProcessor 用于处理实现了 ApplicationContextAware 等接口的 Bean,RequiredAnnotationBeanPostProcessor 用于处理 @Required 注解。
public interface BeanPostProcessor {default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
  1. InstantiationAwareBeanPostProcessor:它是 BeanPostProcessor 的子接口,提供了更多对 Bean 实例化过程的控制,如在实例化前检查是否需要跳过创建、修改属性值等。

十五、SpringMVC 与 WebFlux 的请求处理对比

15.1 基础架构差异