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查找和管理功能,它有多种实现,如XmlBeanFactory
、DefaultListableBeanFactory
等。
1.2 ApplicationContext 扩展
ApplicationContext
是BeanFactory
的子接口,它扩展了更多功能:
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容器的初始化过程主要包括:
- Resource定位:通过ResourceLoader加载配置资源
- BeanDefinition加载:解析配置资源,生成BeanDefinition
- BeanDefinition注册:将BeanDefinition注册到BeanDefinitionRegistry
- 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 自动配置加载流程
自动配置类的加载主要通过以下步骤完成:
- 读取配置文件:从
META-INF/spring.factories
文件中读取所有自动配置类 - 过滤配置类:根据条件注解(如
@ConditionalOnClass
、@ConditionalOnMissingBean
等)过滤不需要的配置类 - 排序配置类:根据
@AutoConfigureOrder
和@AutoConfigureBefore
、@AutoConfigureAfter
注解排序配置类 - 加载配置类:将符合条件的配置类注册到容器中
核心源码如下:
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的请求处理流程主要包括:
- 请求映射:根据请求URL找到对应的Handler
- HandlerAdapter调用:通过HandlerAdapter调用Handler
- Handler执行:执行具体的业务逻辑
- ModelAndView返回:Handler返回ModelAndView
- 视图解析:通过ViewResolver解析视图名称
- 视图渲染:将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支持多种异步请求处理方式:
- Callable:返回一个Callable对象,在另一个线程中执行
- DeferredResult:允许在另一个线程中设置返回结果
- WebAsyncTask:类似于Callable,但提供更多控制选项
- 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 异步请求流程
异步请求的核心流程:
- 主线程接收请求并返回一个异步结果(Callable/DeferredResult等)
- DispatcherServlet释放当前线程,允许其处理其他请求
- 异步任务在另一个线程中执行
- 异步任务完成后,通过AsyncWebRequest通知容器
- 容器重新分派请求,处理结果并返回响应
关键类和接口:
-
WebAsyncManager
:管理异步请求 -
AsyncWebRequest
:异步请求接口 -
DeferredResultProcessingInterceptor
:DeferredResult处理拦截器 -
CallableProcessingInterceptor
:Callable处理拦截器
七、异常处理机制
7.1 异常处理基础
SpringMVC提供了多种异常处理方式:
- @ExceptionHandler:处理控制器内的异常
- @ControllerAdvice + @ExceptionHandler:全局异常处理
- HandlerExceptionResolver:自定义异常解析器
- 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 异常处理流程
异常处理的核心流程:
- 当请求处理过程中抛出异常时,DispatcherServlet捕获异常
- DispatcherServlet遍历所有注册的HandlerExceptionResolver
- 第一个能够处理该异常的Resolver返回ModelAndView
- DispatcherServlet使用返回的ModelAndView进行视图渲染
- 如果没有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 过滤器链与拦截器链
过滤器链的执行流程:
- 客户端请求到达Servlet容器
- 容器按照注册顺序调用所有匹配的过滤器
- 最后一个过滤器调用目标Servlet
- 目标Servlet处理请求
- 响应返回时,过滤器按照相反顺序执行后处理逻辑
拦截器链的执行流程:
- DispatcherServlet接收请求
- HandlerMapping确定Handler和Interceptor链
- 按照注册顺序调用所有Interceptor的preHandle方法
- 调用Handler处理请求
- 按照相反顺序调用所有Interceptor的postHandle方法
- 视图渲染
- 按照相反顺序调用所有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提供了灵活的内容协商机制,支持多种方式确定响应格式:
- 基于请求头的内容协商:根据客户端的Accept头选择合适的响应格式
- 基于URL扩展名的内容协商:通过URL中的扩展名(如.json、.xml)决定响应格式
- 基于请求参数的内容协商:通过请求参数(如
?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 内容协商流程
内容协商的核心流程:
- DispatcherServlet接收到请求后,根据配置的内容协商策略确定请求期望的媒体类型
- Handler处理请求并返回ModelAndView
- DispatcherServlet根据确定的媒体类型选择合适的ViewResolver
- ViewResolver解析视图并返回View
- 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的数据转换机制基于以下核心接口:
- Converter:简单的类型转换器
- ConverterFactory:创建一组相关的转换器
- GenericConverter:支持更复杂的类型转换
- Formatter:格式化器,支持文本与对象之间的双向转换
- 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 会启动验证流程。
- 验证器获取: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();}
}
- 验证执行:以方法参数验证为例,当方法参数标注
@Valid
时,HandlerMethodArgumentResolver
中的ServletRequestMethodArgumentResolver
会触发验证。在解析参数过程中,会调用Validator
的validate
方法对对象进行验证。
// 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;
}
- 错误处理:如果验证失败,会将错误信息封装到
BindingResult
中。若未对错误进行处理,默认会抛出MethodArgumentNotValidException
或BindException
。开发者可以通过@ExceptionHandler
注解在控制器内捕获该异常,也可以使用@ControllerAdvice
进行全局异常处理,将错误信息以合适的格式返回给客户端。
11.3 自定义验证注解
开发者可以通过实现 Constraint
和 ConstraintValidator
接口来自定义验证注解。
- 定义自定义验证注解:
@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 {};
}
- 实现自定义验证器:
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 核心接口与类解析
-
ApplicationEvent
:所有 Spring 事件的基类,继承自java.util.EventObject
。开发者可以通过继承该类自定义事件。
public abstract class ApplicationEvent extends EventObject {private static final long serialVersionUID = 7099057708183571937L;public ApplicationEvent(Object source) {super(source);}
}
-
ApplicationEventPublisher
:事件发布接口,ApplicationContext
继承了该接口,因此所有的ApplicationContext
实例都可以作为事件发布者。AbstractApplicationContext
中通过this.applicationEventPublisher = this;
将自身赋值为事件发布者。
public interface ApplicationEventPublisher {void publishEvent(ApplicationEvent event);void publishEvent(Object event);
}
-
ApplicationListener
:事件监听器接口,实现该接口的类可以监听特定类型的事件。
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {void onApplicationEvent(E event);
}
12.3 事件发布与监听流程
- 事件发布:当需要发布事件时,调用
ApplicationEventPublisher
的publishEvent
方法。例如在AbstractApplicationContext
的finishRefresh
方法中,会发布ContextRefreshedEvent
事件,表示容器刷新完成。
protected void finishRefresh() {// 省略部分代码publishEvent(new ContextRefreshedEvent(this));// 省略部分代码
}
- 事件监听: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 自定义事件与监听器
- 自定义事件:继承
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;}
}
- 自定义监听器:实现
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
启动核心流程
- 创建
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();}// 省略部分代码
}
- 启动应用:调用
SpringApplication
的run
方法启动应用。该方法会完成一系列关键操作:
- 记录启动时间,创建并配置
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 启动过程中的扩展点
-
ApplicationRunner
和CommandLineRunner
:实现这两个接口的 Bean 会在应用启动完成后执行,ApplicationRunner
的run
方法接收ApplicationArguments
参数,CommandLineRunner
的run
方法接收字符串数组参数,方便在启动后执行一些初始化任务。
@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...");}
}
-
ApplicationContextInitializer
:在SpringApplication
创建过程中会加载实现该接口的类,其initialize
方法会在ConfigurableApplicationContext
刷新前执行,可以用于对应用上下文进行提前配置。
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {void initialize(C applicationContext);
}
十四、Spring容器的 Bean 作用域与生命周期
14.1 Bean 作用域详解
Spring 容器支持多种 Bean 作用域,通过 @Scope
注解指定,不同作用域决定了 Bean 的创建和管理方式。
-
singleton
:单例作用域,默认作用域。在整个应用生命周期内,容器中只会存在一个该 Bean 的实例,所有对该 Bean 的请求都会返回同一个实例。容器在初始化时创建单例 Bean。
@Service
@Scope("singleton")
public class SingletonService {// 省略代码
}
-
prototype
:原型作用域。每次请求获取该 Bean 时,容器都会创建一个新的实例。适用于轻量级、无状态的 Bean。
@Service
@Scope("prototype")
public class PrototypeService {// 省略代码
}
-
request
:请求作用域。在一次 HTTP 请求中,容器中只会存在一个该 Bean 的实例,不同请求会创建不同实例。仅适用于 Web 应用。
@Service
@Scope("request")
public class RequestScopedService {// 省略代码
}
-
session
:会话作用域。在一个 HTTP 会话中,容器中只会存在一个该 Bean 的实例,不同会话会创建不同实例。仅适用于 Web 应用。
@Service
@Scope("session")
public class SessionScopedService {// 省略代码
}
-
application
:应用作用域(相当于 ServletContext 作用域)。在整个 Web 应用中,容器中只会存在一个该 Bean 的实例。仅适用于 Web 应用。
14.2 Bean 生命周期流程
- 实例化:容器根据 BeanDefinition 创建 Bean 实例,通过反射调用构造函数完成对象创建。如果 Bean 有多个构造函数,Spring 会通过一定的策略选择合适的构造函数,如首选带有
@Autowired
注解的构造函数。 - 依赖注入:使用
@Autowired
、@Value
等注解完成属性注入或方法注入,为 Bean 设置依赖关系。依赖注入由AutowiredAnnotationBeanPostProcessor
等后置处理器完成。 - 初始化前处理:如果 Bean 实现了
BeanNameAware
、BeanFactoryAware
、ApplicationContextAware
等接口,容器会在此时调用相应的setBeanName
、setBeanFactory
、setApplicationContext
方法,将相关资源注入到 Bean 中。 - 初始化方法调用:如果 Bean 配置了初始化方法(通过
@PostConstruct
注解或init-method
属性指定),容器会调用该方法,进行一些初始化操作。 - 就绪状态:Bean 进入就绪状态,可以被应用程序使用。
- 销毁前处理:当容器关闭时,如果 Bean 实现了
DisposableBean
接口,或配置了销毁方法(通过@PreDestroy
注解或destroy-method
属性指定),容器会调用相应的destroy
方法或销毁方法,进行资源清理等操作。
14.3 后置处理器对生命周期的影响
-
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;}
}
-
InstantiationAwareBeanPostProcessor
:它是BeanPostProcessor
的子接口,提供了更多对 Bean 实例化过程的控制,如在实例化前检查是否需要跳过创建、修改属性值等。
十五、SpringMVC 与 WebFlux 的请求处理对比
15.1 基础架构差异