Springmvc 源码分析
总体流程:DispatcherServlet#doDispatch
1. 获得hander 以及mehtod chain
mappedHandler = getHandler(processedRequest);
2. 获得处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//获得处理器适配器
3. 获得model and view
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
4. 处理视图
applyDefaultViewName(processedRequest, mv);
5. 应用视图
mappedHandler.applyPostHandle(processedRequest, response, mv);
获得handler 代码分析
mappedHandler=getHandler(processedRequest);
1. DispatcherServlet#doDispatch
mappedHandler = getHandler(processedRequest)
2. TestDispatcherServlet#getHandler
super.getHandler(request)
3. DispatcherServlet#getHandler
HandlerExecutionChain handler=mapping.getHandler(request) (mapping is RequestMappingHandlerMapping )
4. AbstractHandlerMapping#getHandler
a. getHandlerInternal
b. lookupHandlerMethod(lookupPath, request)
c. addMatchingMappings(this.**mappingRegistry**.getMappings().keySet(), matches, request)
什么时候把方法以及Url放入到mappingRegistry?
AbstractApplicationContext#finishBeanFactoryInitialization
create Bean flow
...
populateBean
initializeBean
1. invokeAwareMethods
2. invokeInitMethods
((InitializingBean)bean).afterPropertiesSet()->initHandlerMethods()
protected void initHandlerMethods() {
for (String beanName : getCandidateBeanNames()) {
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
processCandidateBean(beanName);
}
}
handlerMethodsInitialized(getHandlerMethods());
}
AbstractHandlerMethodMapping#detectHandlerMethods
protected void detectHandlerMethods(Object handler) {
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 {
return getMappingForMethod(method, userType);
}
});
methods.forEach((method, mapping) -> {
Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
//注册hander与method,放入hashmap中
registerHandlerMethod(handler, invocableMethod, mapping);
});
}
}
什么时候把拦截器放入hanlermapping中,在上面的情况中interceptors是默认的两个,如果我们有自定义的,何时加载?
如何分析呢?先在对应的方法上打断点,之后查看debug栈信息
org.springframework.context.support.AbstractApplicationContext
#refresh->finishBeanFactoryInitializationfinishBean->beanFactory.preInstantiateSingletons()
单例bean初始化之前的准备工作
beanFactory.preInstantiateSingletons()
DefaultListableBeanFactory#preInstantiateSingletons->getBean(beanName)
获得bean实例的具体过程
doGetBean
getSingleton
createBean
doCreateBean
1. createBeanInstance
1) 如果有工厂方法,调用工厂方法生成bean
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
2) 如果有构造方法,返回构造方法创建的对象
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
3) 如果上面两种都没有,调用
instantiateBean(beanName, mbd);
2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
3. populateBean(beanName, mbd, instanceWrapper)
4. initializeBean(beanName, exposedObject, mbd);
5. getDependentBeans(beanName);
6. registerDisposableBeanIfNecessary(beanName, bean, mbd);
此处走的是第2)种情况
autowireConstructor->
argsHolder = createArgumentArray->resolveAutowiredArgument
beanFactory.resolveDependency->doResolveDependency->
resolveMultipleBeans->findAutowireCandidates->addCandidateEntry->resolveCandidate
注入拦截器此处走的createBeanInstance的第1) 种情况来
1. createBeanInstance->
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
2. instantiateUsingFactoryMethod->
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
3. constructorResolver#instantiateUsingFactoryMethod
get the factoryBean, factoryMethodToUse, argsToUse
factoryBeanName:org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration
beanName:requestMappingHandlerMapping
factoryMethodToUse: public org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration.requestMappingHandlerMapping()
即:WebMvcAutoConfiguration中的
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping();
}
...
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);
}
4. SimpleInstantiationStrategy#instantiate
factoryMethod.invoke(factoryBean, args);
即调用
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// Must be @Primary for MvcUriComponentsBuilder to work
return super.requestMappingHandlerMapping();
}
调用:org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#requestMappingHandlerMapping
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
...
handlerMapping.setInterceptors(getInterceptors());
...
getInterceptors方法会得到所有的拦截器信息,但是怎么得到拦截器信息呢?
protected final Object[] getInterceptors() {
if (this.interceptors == null) {
InterceptorRegistry registry = new InterceptorRegistry();
addInterceptors(registry);
//这一步注入了自定义的拦截器,但是这一步的代码并没有发现,问题出在哪里呢?
registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
this.interceptors = registry.getInterceptors();
}
return this.interceptors.toArray();
}
问题1:到这里已经知道在哪里注册拦截器interceptors了,但是从栈中看到是这个过程,为什么呢?
1. ConfigurationClassEnhancer.BeanMethodInterceptor#intercept->cglibMethodProxy.invokeSuper
1. ->WebMvcConfigurationSupport#requestMappingHandlerMapping
1. ->AbstractHandlerMapping#setInterceptors()
原因是上面的factorybean其实是代理对象,代理对象是通过动态代理来实现的,这里调用super方法,也应该调用动态代理来生成父对象,因此会出现上述