您好,登錄后才能下訂單哦!
如果這是你第二次看到師長,說明你在覬覦我的美色!
點贊+關注再看,養(yǎng)成習慣
沒別的意思,就是需要你的窺屏^_^
該趟專車是開往Spring Boot請求處理源碼分析專車,主要用來分析Spring Boot是如何將我們的請求路由到指定的控制器方法以及調(diào)用執(zhí)行。
@RestController
@RequestMapping("/persons")
public class PersonController {
private static List<Person> personList = new ArrayList<>();
static {
personList.add(new Person(10001, "test1"));
personList.add(new Person(10002, "test2"));
personList.add(new Person(10003, "test3"));
personList.add(new Person(10004, "test4"));
personList.add(new Person(10005, "test5"));
}
@GetMapping("/")
public List<Person> list() {
return personList;
}
@GetMapping("/{id}")
public Person get(@PathVariable("id") Integer id) {
Person defaultPerson = new Person(88888, "default");
return personList.stream().filter(person -> Objects.equals(person.getId(), id)).findFirst().orElse(defaultPerson);
}
@PostMapping("/")
public void add(@RequestBody Person person) {
personList.add(person);
}
@PutMapping("/")
public void update(@RequestBody Person person) {
personList.removeIf(p -> Objects.equals(p.getId(), person.getId()));
personList.add(person);
}
}
示例代碼提供了GET、POST、PUT請求,接下里我們會結合示例進行源碼分析
此次分析主要從2個大的方面進行分析:請求初始化、請求處理
一次完成的請求流程就是請求--->處理--->響應,業(yè)務邏輯處理最終交由我們創(chuàng)建的Servlet來進行處理。以前在使用Spring MVC框架的時候,我們都會在web.xml中配置一個DispathcherServlet。接下來就讓我們來看看DispathcherServlet的類圖
從如上圖可以清晰的看到DispatcherServlet的繼承關系。其中一個名為HttpServlet的類,如果寫過Servlet的應該都比較的熟悉,以往基于Servlet開發(fā),都會創(chuàng)建一個Servlet實現(xiàn)類,繼承HttpServlet并重寫service方法,最后在web.xml中配置我們我們創(chuàng)建的Servlet實現(xiàn)類,這樣我們就可以使用創(chuàng)建的Servlet實現(xiàn)類來處理我們的web請求了。
在我們第一次請求的時候會進行Servlet的初始化,主要用來初始化資源。HttpServlet的init方法由父類GenericServlet聲明,由子類HttpServletBean實現(xiàn)。
初始化方法:HttpServletBean#init
@Override
public final void init() throws ServletException {
// ...省略部分代碼
// Let subclasses do whatever initialization they like.
// 暴露出去一個方法,可以讓子類初始化一些自己想要初始化的內(nèi)容
initServletBean();
}
創(chuàng)建WebApplicationContext:FrameworkServlet#initServletBean
@Override
protected final void initServletBean() throws ServletException {
// ...省略部分代碼
try {
// 初始化WebApplicationContext對象
this.webApplicationContext = initWebApplicationContext();
// 空實現(xiàn)
initFrameworkServlet();
}
// ...省略部分代碼
}
初始化WebApplicationContext對象:FrameworkServlet#initWebApplicationContext
protected WebApplicationContext initWebApplicationContext() {
// 獲取WebApplicationContext對象
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
// ... 省略部分代碼
if (!this.refreshEventReceived) {
// Either the context is not a ConfigurableApplicationContext with refresh
// support or the context injected at construction time had already been
// refreshed -> trigger initial onRefresh manually here.
synchronized (this.onRefreshMonitor) {
// 刷新資源
onRefresh(wac);
}
}
if (this.publishContext) {
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
}
return wac;
}
刷新資源:DispatcherServlet#onRefresh
@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
初始化策略:DispatcherServlet#initStrategies
protected void initStrategies(ApplicationContext context) {
// 初始化多文件解析器
initMultipartResolver(context);
// 初始化本地化解析器
initLocaleResolver(context);
// 初始化主題解析器
initThemeResolver(context);
// 初始化HandlerMapping
initHandlerMappings(context);
// 初始化HandlerAdapter
initHandlerAdapters(context);
// 初始化異常解析器
initHandlerExceptionResolvers(context);
// 初始化請求到視圖名稱翻譯器
initRequestToViewNameTranslator(context);
// 初始化視圖解析器
initViewResolvers(context);
initFlashMapManager(context);
}
來看一下初始化HandlerMapping實現(xiàn):DispatcherServlet#initHandlerMappings
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
// 從IOC容器中獲取類型為HandlerMapping的bean
// 對應的bean有RequestMappingHandlerMapping、SimpleUrlHandlerMapping、WelcomePageHandlerMapping
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<>(matchingBeans.values());
// We keep HandlerMappings in sorted order.
// 對HandlerMapping進行排序
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
}
通過對初始化HandlerMapping實現(xiàn)的分析,我們可以得出,所有的初始化操作就是從IOC容器中獲取相應類型的Bean,然后進行屬性賦值。
既然能從IOC容器中獲取到HandlerMapping bean,那么一定存在定義bean 的地方。打開WebMvcAutoConfiguration類,可以看到如下代碼
/**
* Configuration equivalent to {@code @EnableWebMvc}.
* 此配置等同于使用@EnableWebMvc注解
*/
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
private final WebMvcProperties mvcProperties;
private final ListableBeanFactory beanFactory;
private final WebMvcRegistrations mvcRegistrations;
public EnableWebMvcConfiguration(
ObjectProvider<WebMvcProperties> mvcPropertiesProvider,
ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider,
ListableBeanFactory beanFactory) {
this.mvcProperties = mvcPropertiesProvider.getIfAvailable();
this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique();
this.beanFactory = beanFactory;
}
// 聲明RequestMappingHandlerAdapter bean
@Bean
@Override
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties == null
|| this.mvcProperties.isIgnoreDefaultModelOnRedirect());
return adapter;
}
// 聲明RequestMappingHandlerMapping bean
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping();
}
}
在如上代碼中可以看到HandlerAdapter和HandlerMapping bean的聲明
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// 創(chuàng)建RequestMappingHandlerMapping對象
RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
// 設置屬性
mapping.setOrder(0);
// 設置攔截器
mapping.setInterceptors(getInterceptors());
mapping.setContentNegotiationManager(mvcContentNegotiationManager());
mapping.setCorsConfigurations(getCorsConfigurations());
// ...省略部分代碼
return mapping;
}
可以看到除了創(chuàng)建RequestMappingHandlerMapping對象,其它的都是設置屬性信息,接下來重點分析創(chuàng)建對象部分的代碼
WebMvcConfigurationSupport#createRequestMappingHandlerMapping
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
return new RequestMappingHandlerMapping();
}
可以創(chuàng)建RequestMappingHandlerMapping對象的代碼很簡單,就是調(diào)用了無參數(shù)構造進行初始化。但是通過查看RequestMappingHandlerMapping的繼承關系,我們可以看到該類實現(xiàn)了InitializingBean接口,這也就告訴我們當看到很簡單的代碼的時候,我們就要看看類的繼承關系,來看看是否使用其他形式進行邏輯實現(xiàn)。
既然實現(xiàn)了InitializingBean接口,那就看看創(chuàng)建bean后的初始化方法afterPropertiesSet
@Override
public void afterPropertiesSet() {
this.config = new RequestMappingInfo.BuilderConfiguration();
this.config.setUrlPathHelper(getUrlPathHelper());
this.config.setPathMatcher(getPathMatcher());
this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);
this.config.setTrailingSlashMatch(this.useTrailingSlashMatch);
this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch);
this.config.setContentNegotiationManager(getContentNegotiationManager());
// 調(diào)用父類的初始化方法
super.afterPropertiesSet();
}
@Override
**public** **void** **afterPropertiesSet**() {
// 初始化處理方法
initHandlerMethods();
}
初始化處理方法:AbstractHandlerMethodMapping#initHandlerMethods
protected void initHandlerMethods() {
// 獲取并遍歷候選bean名稱,候選bean就是從IOC容器中獲取類型為Object的bean名稱,也就是所有的Bean名稱
for (String beanName : getCandidateBeanNames()) {
// 如果bean的名稱不以“scopedTarget.”開頭,才進行處理
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
// 處理候選bean名稱
processCandidateBean(beanName);
}
}
handlerMethodsInitialized(getHandlerMethods());
}
處理候選bean名稱:AbstractHandlerMethodMapping#processCandidateBean
protected void processCandidateBean(String beanName) {
Class<?> beanType = null;
try {
// 根據(jù)bean的名稱獲取對應bean的類型
beanType = obtainApplicationContext().getType(beanName);
}
catch (Throwable ex) {
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
if (logger.isTraceEnabled()) {
logger.trace("Could not resolve type for bean '" + beanName + "'", ex);
}
}
// 如果bean的類型不為空并且對應類上含有@Controller注解或者@RequestMapping注解
if (beanType != null && isHandler(beanType)) {
// 推斷處理方法
detectHandlerMethods(beanName);
}
}
推斷處理方法:AbstractHandlerMethodMapping#detectHandlerMethods
protected void detectHandlerMethods(Object handler) {
// 根據(jù)bean名稱獲取類型
Class<?> handlerType = (handler instanceof String ?
obtainApplicationContext().getType((String) handler) : handler.getClass());
if (handlerType != null) {
Class<?> userType = ClassUtils.getUserClass(handlerType);
// 獲取處理方法
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
(MethodIntrospector.MetadataLookup<T>) method -> {
try {
// selectMethods方法獲取當前類中所有的方法,針對PersonController類就有l(wèi)ist、get、add、update四個方法,遍歷這四個方法,分別創(chuàng)建對應的RequestMappingInfo對象
// 根據(jù)method獲取RequestMappingInfo對象
return getMappingForMethod(method, userType);
}
});
if (logger.isTraceEnabled()) {
logger.trace(formatMappings(userType, methods));
}
methods.forEach((method, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
registerHandlerMethod(handler, invocableMethod, mapping);
});
}
}
根據(jù)method獲取RequestMappingInfo對象:RequestMappingHandlerMapping#getMappingForMethod
@Override
@Nullable
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
// 根據(jù)method對象創(chuàng)建RequestMappingInfo對象
RequestMappingInfo info = createRequestMappingInfo(method);
if (info != null) {
// 如果當前方法所在的類也含有@RequestMapping對象,那么也創(chuàng)建一個RequestMappingInfo對象
RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
if (typeInfo != null) {
// 將兩個RequestMappingInfo對象進行合并,比如我們PersonController上指定@RequestMapping("/persons"),針對list方法,list方法上指定@RequestMapping("/"),那么合并后的映射路徑就是/persons/
info = typeInfo.combine(info);
}
String prefix = getPathPrefix(handlerType);
if (prefix != null) {
info = RequestMappingInfo.paths(prefix).build().combine(info);
}
}
// 返回RequestMappingInfo對象
return info;
}
回到推斷處理方法中:AbstractHandlerMethodMapping#detectHandlerMethods
protected void detectHandlerMethods(Object handler) {
// 根據(jù)bean名稱獲取類型
Class<?> handlerType = (handler instanceof String ?
obtainApplicationContext().getType((String) handler) : handler.getClass());
if (handlerType != null) {
Class<?> userType = ClassUtils.getUserClass(handlerType);
// 獲取處理方法,每個方法都有對應的RequestMappingInfo對象
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
(MethodIntrospector.MetadataLookup<T>) method -> {
try {
// selectMethods方法中當前類中所有的方法,針對PersonController類就有l(wèi)ist、get、add、update四個方法,遍歷這四個方法,分別創(chuàng)建對應的RequestMappingInfo對象
// 根據(jù)method獲取RequestMappingInfo對象
return getMappingForMethod(method, userType);
}
});
if (logger.isTraceEnabled()) {
logger.trace(formatMappings(userType, methods));
}
// 遍歷處理方法
methods.forEach((method, mapping) -> {
// 獲取可以執(zhí)行的method對象
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
// 注冊處理方法
registerHandlerMethod(handler, invocableMethod, mapping);
});
}
}
注冊處理方法:AbstractHandlerMethodMapping.MappingRegistry#register
public void register(T mapping, Object handler, Method method) {
// 加寫鎖,加鎖是因為我們可以在代碼中手動注冊處理方法,為了防止并發(fā)問題,此處需要加鎖處理
this.readWriteLock.writeLock().lock();
try {
// 創(chuàng)建HandlerMethod對象
HandlerMethod handlerMethod = createHandlerMethod(handler, method);
assertUniqueMethodMapping(handlerMethod, mapping);
// 將RequestMappingInfo對象和HandlerMethod對象添加到map集合中
this.mappingLookup.put(mapping, handlerMethod);
List<String> directUrls = getDirectUrls(mapping);
for (String url : directUrls) {
// 將url和RequestMappingInfo對象添加到map集合中
this.urlLookup.add(url, mapping);
}
String name = null;
if (getNamingStrategy() != null) {
name = getNamingStrategy().getName(handlerMethod, mapping);
addMappingName(name, handlerMethod);
}
CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
if (corsConfig != null) {
this.corsLookup.put(handlerMethod, corsConfig);
}
// 將RequestMappingInfo和MappingRegistration對象添加到map集合中
this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
}
finally {
// 釋放鎖
this.readWriteLock.writeLock().unlock();
}
}
所有方法遍歷完成后的結果如下:
到此RequestMappingHandlerMapping對象創(chuàng)建初始化就結束了
創(chuàng)建RequestMappingHandlerAdapter:WebMvcAutoConfiguration.EnableWebMvcConfiguration#requestMappingHandlerAdapter
@Bean
@Override
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
// 調(diào)用父類創(chuàng)建RequestMappingHandlerAdapter對象
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
// ...省略部分代碼
return adapter;
}
調(diào)用父類創(chuàng)建RequestMappingHandlerAdapter:WebMvcConfigurationSupport#requestMappingHandlerAdapter
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
// 創(chuàng)建RequestMappingHandlerAdapter對象
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
// 省略部分代碼
return adapter;
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
// 匹配HandlerMethod并包裝成HandlerExecutionChain對象
mappedHandler = getHandler(processedRequest);
}
獲取HandlerExecutionChain對象:DispatcherServlet#getHandler
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
if (this.handlerMappings != null) {
// 遍歷所有的HandlerMapping
for (HandlerMapping mapping : this.handlerMappings) {
// 根據(jù)HandlerMapping獲取HandlerExecutionChain對象,此處的HandlerMapping就是上面分析過的RequestMappingHandlerMapping對象
HandlerExecutionChain handler = mapping.getHandler(request);
// 如果獲取到HandlerExecutionChain對象,那么直接將HandlerExecutionChain對象返回
if (handler != null) {
return handler;
}
}
}
return null;
}
根據(jù)HandlerMapping獲取HandlerExecutionChain對象:AbstractHandlerMapping#getHandler
@Override
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 獲取HandlerMethod對象
Object handler = getHandlerInternal(request);
// ...省略部分代碼
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
// ...省略部分代碼
return executionChain;
}
獲取HandlerMethod對象
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 獲取請求的路徑,假設此處請求的路徑為/persons/
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
// 加鎖
this.mappingRegistry.acquireReadLock();
try {
// 尋找HandlerMethod對象
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
// 獲取HandlerMethod所在類對應的bean,然后創(chuàng)建HandlerMethod對象
return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
}
finally {
// 釋放鎖
this.mappingRegistry.releaseReadLock();
}
}
尋找HandlerMethod對象:AbstractHandlerMethodMapping#lookupHandlerMethod
在該方法之前再看一下上文中對RequestMappingHandlerMapping分析的結果
@Nullable
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
List<Match> matches = new ArrayList<>();
// 從urlLookup屬性中找到當前請求路徑對應的RequestMappingInfo信息
// 假設請求的路徑為/persons/,那么此處得到的結果有3個
List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
if (directPathMatches != null) {
// 尋找最匹配的RequestMappingInfo
// 匹配的方式包括:請求方法、請求header、請求參數(shù)等
addMatchingMappings(directPathMatches, matches, request);
}
if (matches.isEmpty()) {
// No choice but to go through all mappings...
addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
}
if (!matches.isEmpty()) {
Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
matches.sort(comparator);
Match bestMatch = matches.get(0);
if (matches.size() > 1) {
if (logger.isTraceEnabled()) {
logger.trace(matches.size() + " matching mappings: " + matches);
}
if (CorsUtils.isPreFlightRequest(request)) {
return PREFLIGHT_AMBIGUOUS_MATCH;
}
Match secondBestMatch = matches.get(1);
// 如果存在多個匹配結果,就報錯
if (comparator.compare(bestMatch, secondBestMatch) == 0) {
Method m1 = bestMatch.handlerMethod.getMethod();
Method m2 = secondBestMatch.handlerMethod.getMethod();
String uri = request.getRequestURI();
throw new IllegalStateException(
"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
}
}
request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
handleMatch(bestMatch.mapping, lookupPath, request);
// 返回匹配的HandlerMethod
return bestMatch.handlerMethod;
}
else {
return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
}
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
}
獲取HandlerAdapter:DispatcherServlet#getHandlerAdapter
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
// 如果當前HandlerAdapter支持當前要處理的HnadlerMethod,那么就返回此HandlerAdapter
if (adapter.supports(handler)) {
return adapter;
}
}
}
throw new ServletException("No adapter for handler [" + handler +
"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}
匹配方法:此處拿RequestMappingHandlerAdapter舉例,調(diào)用AbstractHandlerMethodAdapter#supports
public final boolean supports(Object handler) {
// 如果當前的hander是HandlerMethod,則返回true;后一個表達式直接返回的就是true
return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
}
從如上分析可以得出的結論就是最終返回的HandlerAdapter為RequestMappingHandlerAdapter
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
}
處理目標方法:RequestMappingHandlerAdapter#handleInternal
@Override
protected ModelAndView handleInternal(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ModelAndView mav;
checkRequest(request);
// Execute invokeHandlerMethod in synchronized block if required.
if (this.synchronizeOnSession) {
// ...省略部分代碼
}
else {
// No synchronization on session demanded at all...
// 調(diào)用HandlerMethod方法
mav = invokeHandlerMethod(request, response, handlerMethod);
}
// ...省略部分代碼
return mav;
}
調(diào)用HandlerMethod方法:RequestMappingHandlerAdapter#invokeHandlerMethod
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
ServletWebRequest webRequest = new ServletWebRequest(request, response);
try {
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
// 創(chuàng)建ServletInvocableHandlerMethod對象,就是把handlerMethod對象的屬性賦值給ServletInvocableHandlerMethod對象的屬性
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
// ...省略部分代碼
// 調(diào)用方法并處理返回值
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return getModelAndView(mavContainer, modelFactory, webRequest);
}
finally {
webRequest.requestCompleted();
}
}
調(diào)用方法并處理返回值:ServletInvocableHandlerMethod#invokeAndHandle
public void invokeAndHandle(ServletWebRequest webRequest,
ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 執(zhí)行請求,獲取返回值
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
setResponseStatus(webRequest);
// ...省略部分代碼
mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
// 處理返回值
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
}
執(zhí)行請求:InvocableHandlerMethod#invokeForRequest
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 獲取方法參數(shù)
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
// 目標方法調(diào)用
return doInvoke(args);
}
目標方法調(diào)用:InvocableHandlerMethod#doInvoke
@Nullable
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
// 通過反射執(zhí)行目標方法
return getBridgedMethod().invoke(getBean(), args);
}
// ...省略部分代碼
}
到此請求處理的源碼分析就結束了,最終再來看看doDispatch完整的方法:DispatcherServlet#doDispatch
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);
// Determine handler for the current request.
// 1、獲取handler
mappedHandler = getHandler(processedRequest);
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// Determine handler adapter for the current request.
// 2、獲取HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
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;
}
}
// 執(zhí)行攔截器的前置方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
// 調(diào)用目標方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
applyDefaultViewName(processedRequest, mv);
// 執(zhí)行攔截器的處理方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
catch (Throwable err) {
// As of 4.3, we're processing Errors thrown from handler methods as well,
// making them available for @ExceptionHandler methods and other scenarios.
dispatchException = new NestedServletException("Handler dispatch failed", err);
}
// 處理結果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
// 執(zhí)行攔截器的后置方法,常用語釋放資源
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Throwable err) {
// 執(zhí)行攔截器的后置方法,常用語釋放資源
triggerAfterCompletion(processedRequest, response, mappedHandler,
new NestedServletException("Handler processing failed", err));
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
一次請求原理如下:
如果是基于微服務開發(fā),那么該如何定義我們的服務?
定義微服務接口:
@RequestMapping("/persons")
public interface PersonApi {
/**
* list
*
* @return
*/
@GetMapping("/")
List<Person> list();
/**
* get
*
* @param id
* @return
*/
@GetMapping("/{id}")
Person get(@PathVariable("id") Integer id);
/**
* add
*
* @param person
* @return
*/
@PostMapping("/")
void add(@RequestBody Person person);
/**
* update
*
* @param person
* @return
*/
@PutMapping("/")
void update(@RequestBody Person person);
}
定義接口實現(xiàn):
@RestController
public class PersonController implements PersonApi {
private static List<Person> personList = new ArrayList<>();
static {
personList.add(new Person(10001, "test1"));
personList.add(new Person(10002, "test2"));
personList.add(new Person(10003, "test3"));
personList.add(new Person(10004, "test4"));
personList.add(new Person(10005, "test5"));
}
@Override
public List<Person> list() {
return personList;
}
@Override
public Person get(Integer id) {
Person defaultPerson = new Person(88888, "default");
return personList.stream().filter(person -> Objects.equals(person.getId(), id)).findFirst().orElse(defaultPerson);
}
@Override
public void add(Person person) {
personList.add(person);
}
@Override
public void update(Person person) {
personList.removeIf(p -> Objects.equals(p.getId(), person.getId()));
personList.add(person);
}
}
【原創(chuàng)】001 | 搭上SpringBoot自動注入源碼分析專車
【原創(chuàng)】002 | 搭上SpringBoot事務源碼分析專車
【原創(chuàng)】003 | 搭上基于SpringBoot事務思想實戰(zhàn)專車
【原創(chuàng)】004 | 搭上SpringBoot事務詭異事件分析專車
最后
師長,專注分享Java進階、架構技術、高并發(fā)、微服務、BAT面試、redis專題、JVM調(diào)優(yōu)、Springboot源碼、mysql優(yōu)化等20大進階架構專題。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。