springmvc源码分析

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方法,也应该调用动态代理来生成父对象,因此会出现上述

动态代理对象生成的过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值