Spring源码中的工具类
文章目录
- spring-core
- StandardAnnotationMetadata 取类描述信息
- AnnotatedElementUtils、AnnotationUtils查找类注释
- DefaultConversionService 默认转换器,设包含一组类型转换器
- SimpleCommandLineArgsParser 简单的解析命令行数据
- JOptCommandLinePropertySource 扩展自CommandLinePropertySource解析命令行参数
- MutablePropertySources 包含一组资源文件,可以设置顺序
- ResourceUtils 加载资源
- StylerUtils 指定toString的打印格式
- SimpleMetadataReaderFactory 读取元数据,5.2新加
- AnnotationTypeFilter 判断指定类是否有某个注解
- AspectJTypeFilter 判断类和指定描述是否一致
- ExceptionDepthComparator 异常深度比较器
- StopWatch 秒表,监视任务性能耗时
- StreamUtils FileCopyUtils FileSystemUtils 流、文件操作
- GenericTypeResolver 解析泛型
- spring-beans
- SimpleBeanDefinitionRegistry BeanDefinitionRegistry接口的简单实现
- BeanExpressionContext 上下文对象,用于对bean定义中的表达式求值
- PropertyResourceConfigurer 实现了BeanFactoryPostProcessor,可以在Bean定义时修改值
- PropertyPlaceholderConfigurer 继承PropertyResourceConfigurer,解析占位符,5.2已启用
- YamlPropertiesFactoryBean 解析yml文件
- CustomEditorConfigurer 实现了BeanFactoryPostProcessor,可以自定义编辑器,改包下还有大量其他编辑器
- PropertyEditorRegistrySupport PropertyEditorRegistry接口的基本实现。提供对默认编辑器和自定义编辑器的管理。主要用作BeanWrapperImpl的基类
- TypeConverterDelegate 类型转换为指定类型的助手类,由BeanWrapperImpl和SimpleTypeConverter调用
- BeanUtils 对象复制、实例化、方法查找、属性描述等
- ArgumentConvertingMethodInvoker 通过参数调用方法,支持重载
- PagedListHolder 将对象以分页形式展示
- BeanWrapperImpl 包装指定类
- CachedIntrospectionResults 缓存PropertyDescriptor,不建议应用程序使用
- ExtendedBeanInfoFactory、ExtendedBeanInfo 解决链式调用问题
- MutablePropertyValues PropertyValues的简单实现
- BeanDefinitionBuilder 构建BeanDefinition
- BeanDefinitionReaderUtils 注册bean
- PropertyAccessorUtils bean属性访问
- spring-aop
- AnnotationAwareAspectJAutoProxyCreator @Aspect动态创建代理
- AopProxyUtils
- completeProxiedInterfaces(AdvisedSupport advised)
- spring-context
- ConfigurationClassPostProcessor 扫描注解,进行注册bean
- ConfigurationClassParser 解析@Configuration的注解类
- ConfigurationClassEnhancer 代理增强@Configuration修饰的类,实现对@Bean发现的拦截
- PostProcessorRegistrationDelegate AbstractApplicationContext的后处理器处理的委托。
- StandardBeanExpressionResolver spEl表达式解析
- ResourceEditorRegistrar 添加资源编码器,对URL\File等资源解析
- AnnotationMetadata.introspect(class) 自省方式获取bean
- AnnotationConfigUtils.attributesFor(metadata, Bean.class) 获取bean注释信息
- AnnotationConfigUtils 配置了大量和注释相关的上下信息,AnnotationConfigApplicationContext回去使用
- spring-webmvc
- RequestMappingHandlerAdapter
spring-core
整合了asm和cglib包,并定制了部分功能
StandardAnnotationMetadata 取类描述信息
根据注解生成AnnotatedGenericBeanDefinition时很有用
StandardAnnotationMetadata.from(type);
AnnotatedElementUtils、AnnotationUtils查找类注释
Method m = Leaf.class.getMethod("annotatedOnLeaf");
assertThat(m.getAnnotation(Order.class)).isNotNull();
assertThat(AnnotationUtils.getAnnotation(m, Order.class)).isNotNull();
assertThat(AnnotationUtils.findAnnotation(m, Order.class)).isNotNull();
DefaultConversionService 默认转换器,设包含一组类型转换器
assertThat(conversionService.convert("false", Boolean.class)).isEqualTo(false);
assertThat(conversionService.convert("off", Boolean.class)).isEqualTo(false);
assertThat(conversionService.convert("no", Boolean.class)).isEqualTo(false);
assertThat(conversionService.convert("0", Boolean.class)).isEqualTo(false);
assertThat(conversionService.convert("FALSE", Boolean.class)).isEqualTo(false);
assertThat(conversionService.convert("OFF", Boolean.class)).isEqualTo(false);
assertThat(conversionService.convert("NO", Boolean.class)).isEqualTo(false);
SimpleCommandLineArgsParser 简单的解析命令行数据
final SimpleCommandLineArgsParser parser = new SimpleCommandLineArgsParser();
CommandLineArgs args = parser.parse("--o1");
assertThat(args.containsOption("o1")).isTrue();
assertThat(args.getOptionValues("o1")).isEqualTo(Collections.EMPTY_LIST);
JOptCommandLinePropertySource 扩展自CommandLinePropertySource解析命令行参数
@Test
void withRequiredArg_andMultipleArgsPresent_usingDelimiter() {OptionParser parser = new OptionParser();parser.accepts("foo").withRequiredArg().withValuesSeparatedBy(',');OptionSet options = parser.parse("--foo=bar,baz,biz");CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(options);assertThat(ps.getOptionValues("foo")).containsExactly("bar", "baz", "biz");assertThat(ps.getProperty("foo")).isEqualTo("bar,baz,biz");
}@Test
void withRequiredArg_andMultipleArgsPresent_usingRepeatedOption() {OptionParser parser = new OptionParser();parser.accepts("foo").withRequiredArg().withValuesSeparatedBy(',');OptionSet options = parser.parse("--foo=bar", "--foo=baz", "--foo=biz");CommandLinePropertySource<?> ps = new JOptCommandLinePropertySource(options);assertThat(ps.getOptionValues("foo")).containsExactly("bar", "baz", "biz");assertThat(ps.getProperty("foo")).isEqualTo("bar,baz,biz");
}
MutablePropertySources 包含一组资源文件,可以设置顺序
MutablePropertySources sources = new MutablePropertySources();
sources.addLast(new MockPropertySource("b").withProperty("p1", "bValue"));
sources.addLast(new MockPropertySource("d").withProperty("p1", "dValue"));
sources.addLast(new MockPropertySource("f").withProperty("p1", "fValue"));assertThat(sources.size()).isEqualTo(3);
assertThat(sources.contains("a")).isFalse();
assertThat(sources.contains("b")).isTrue();
assertThat(sources.contains("c")).isFalse();
assertThat(sources.contains("d")).isTrue();
assertThat(sources.contains("e")).isFalse();
assertThat(sources.contains("f")).isTrue();
assertThat(sources.contains("g")).isFalse();assertThat(sources.get("b")).isNotNull();
assertThat(sources.get("b").getProperty("p1")).isEqualTo("bValue");
assertThat(sources.get("d")).isNotNull();
assertThat(sources.get("d").getProperty("p1")).isEqualTo("dValue");sources.addBefore("b", new MockPropertySource("a"));
sources.addAfter("b", new MockPropertySource("c"));
ResourceUtils 加载资源
StylerUtils 指定toString的打印格式
SimpleMetadataReaderFactory 读取元数据,5.2新加
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponentSubClass.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(AnnotatedComponent.class.getName());
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
assertThat(metadata.getClassName()).isEqualTo(AnnotatedComponent.class.getName());
assertThat(metadata.isInterface()).isFalse();
assertThat(metadata.isAnnotation()).isFalse();
assertThat(metadata.isAbstract()).isFalse();
assertThat(metadata.isConcrete()).isTrue();
assertThat(metadata.hasSuperClass()).isTrue();
assertThat(metadata.getSuperClassName()).isEqualTo(Object.class.getName());
assertThat(metadata.getInterfaceNames().length).isEqualTo(1);
assertThat(metadata.getInterfaceNames()[0]).isEqualTo(Serializable.class.getName());assertThat(metadata.isAnnotated(Component.class.getName())).isTrue();assertThat(metadata.isAnnotated(NamedComposedAnnotation.class.getName())).isTrue();assertThat(metadata.hasAnnotation(Component.class.getName())).isTrue();
assertThat(metadata.hasAnnotation(Scope.class.getName())).isTrue();
assertThat(metadata.hasAnnotation(SpecialAttr.class.getName())).isTrue();
Set<MethodMetadata> methods = classMetadata.getAnnotatedMethods(TestAutowired.class.getName());
assertThat(methods).hasSize(1);
for (MethodMetadata methodMetadata : methods) {assertThat(methodMetadata.isAnnotated(TestAutowired.class.getName())).isTrue();
}
AnnotationTypeFilter 判断指定类是否有某个注解
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
String classUnderTest = "example.type.AnnotationTypeFilterTestsTypes$SomeSubclassOfSomeComponent";
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(classUnderTest);AnnotationTypeFilter filter = new AnnotationTypeFilter(InheritedAnnotation.class);
assertThat(filter.match(metadataReader, metadataReaderFactory)).isTrue();
ClassloadingAssertions.assertClassNotLoaded(classUnderTest);
AspectJTypeFilter 判断类和指定描述是否一致
String type = "example.type.AspectJTypeFilterTestsTypes$SomeClass";
String typePattern = "example.type.AspectJTypeFilterTestsTypes.SomeClassX";
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(type);AspectJTypeFilter filter = new AspectJTypeFilter(typePattern, getClass().getClassLoader());
assertThat(filter.match(metadataReader, metadataReaderFactory)).isFalse();
ClassloadingAssertions.assertClassNotLoaded(type);
ExceptionDepthComparator 异常深度比较器
Class<? extends Throwable> foundClass = ExceptionDepthComparator.findClosestMatch(Arrays.asList(SameDepthException.class, TargetException.class), new TargetException());
assertThat(foundClass).isEqualTo(TargetException.class);
StopWatch 秒表,监视任务性能耗时
StreamUtils FileCopyUtils FileSystemUtils 流、文件操作
InputStream inputStream = spy(new ByteArrayInputStream(bytes));
byte[] actual = StreamUtils.copyToByteArray(inputStream);Charset charset = Charset.defaultCharset();
InputStream inputStream = spy(new ByteArrayInputStream(string.getBytes(charset)));
String actual = StreamUtils.copyToString(inputStream, charset);ByteArrayInputStream in = new ByteArrayInputStream(content);
ByteArrayOutputStream out = new ByteArrayOutputStream(content.length);
int count = FileCopyUtils.copy(in, out);String content = "content";
StringReader in = new StringReader(content);
StringWriter out = new StringWriter();
int count = FileCopyUtils.copy(in, out);String content = "content";
StringWriter out = new StringWriter();
FileCopyUtils.copy(content, out);String content = "content";
StringReader in = new StringReader(content);
String result = FileCopyUtils.copyToString(in);File src = new File("./tmp/src");
File child = new File(src, "child");
File grandchild = new File(child, "grandchild");grandchild.mkdirs();File bar = new File(child, "bar.txt");
bar.createNewFile();assertThat(src.exists()).isTrue();
assertThat(child.exists()).isTrue();
assertThat(grandchild.exists()).isTrue();
assertThat(bar.exists()).isTrue();File dest = new File("./dest");
FileSystemUtils.copyRecursively(src, dest);assertThat(dest.exists()).isTrue();
assertThat(new File(dest, child.getName()).exists()).isTrue();FileSystemUtils.deleteRecursively(src);
GenericTypeResolver 解析泛型
map = GenericTypeResolver.getTypeVariableMap(MySimpleInterfaceType.class);
assertThat(map.toString()).isEqualTo("{T=class java.lang.String}");map = GenericTypeResolver.getTypeVariableMap(MyCollectionInterfaceType.class);
assertThat(map.toString()).isEqualTo("{T=java.util.Collection<java.lang.String>}");
spring-beans
依赖spring-core
SimpleBeanDefinitionRegistry BeanDefinitionRegistry接口的简单实现
只提供注册表功能,没有内置的工厂功能。例如,可以用于测试bean定义读取器
BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
AnnotatedBeanDefinition bd = new AnnotatedGenericBeanDefinition(ComponentWithName.class);
String beanName = this.beanNameGenerator.generateBeanName(bd, registry);
assertThat(beanName).as("The generated beanName must *never* be null.").isNotNull();
assertThat(StringUtils.hasText(beanName)).as("The generated beanName must *never* be blank.").isTrue();
assertThat(beanName).isEqualTo("walden");
BeanExpressionContext 上下文对象,用于对bean定义中的表达式求值
PropertyResourceConfigurer 实现了BeanFactoryPostProcessor,可以在Bean定义时修改值
PropertyPlaceholderConfigurer 继承PropertyResourceConfigurer,解析占位符,5.2已启用
5.2后推荐使用 PropertySourcesPlaceholderConfigurer
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new GenericBeanDefinition());
builder.beanDefinition.setBeanClass(TestBean.class);bf.registerBeanDefinition("testBean",builder.addPropertyValue("name", "${my.name}").getBeanDefinition());PropertyPlaceholderConfigurer pc = new PropertyPlaceholderConfigurer();Resource resource = new ClassPathResource("PropertyPlaceholderConfigurerTests.properties", this.getClass());pc.setLocation(resource);pc.postProcessBeanFactory(bf);
YamlPropertiesFactoryBean 解析yml文件
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(new ByteArrayResource("foo: bar\nspam:\n foo: baz".getBytes()));
Properties properties = factory.getObject();
assertThat(properties.getProperty("foo")).isEqualTo("bar");
assertThat(properties.getProperty("spam.foo")).isEqualTo("baz");
CustomEditorConfigurer 实现了BeanFactoryPostProcessor,可以自定义编辑器,改包下还有大量其他编辑器
DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
CustomEditorConfigurer cec = new CustomEditorConfigurer();
final DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN);
cec.setPropertyEditorRegistrars(new PropertyEditorRegistrar[] {new PropertyEditorRegistrar() {@Overridepublic void registerCustomEditors(PropertyEditorRegistry registry) {registry.registerCustomEditor(Date.class, new CustomDateEditor(df, true));}}});
cec.postProcessBeanFactory(bf);MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("date", "2.12.1975");
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
bd1.setPropertyValues(pvs);
bf.registerBeanDefinition("tb1", bd1);
pvs = new MutablePropertyValues();
pvs.add("someMap[myKey]", new TypedStringValue("2.12.1975", Date.class));
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
bd2.setPropertyValues(pvs);
bf.registerBeanDefinition("tb2", bd2);TestBean tb1 = (TestBean) bf.getBean("tb1");
assertThat(tb1.getDate()).isEqualTo(df.parse("2.12.1975"));
TestBean tb2 = (TestBean) bf.getBean("tb2");
assertThat(tb2.getSomeMap().get("myKey")).isEqualTo(df.parse("2.12.1975"));
PropertyEditorRegistrySupport PropertyEditorRegistry接口的基本实现。提供对默认编辑器和自定义编辑器的管理。主要用作BeanWrapperImpl的基类
@Nullable
public PropertyEditor getDefaultEditor(Class<?> requiredType) {if (!this.defaultEditorsActive) {return null;}if (this.overriddenDefaultEditors != null) {PropertyEditor editor = this.overriddenDefaultEditors.get(requiredType);if (editor != null) {return editor;}}if (this.defaultEditors == null) {// 核心,懒加载所有编辑器createDefaultEditors();}return this.defaultEditors.get(requiredType);
}private void createDefaultEditors() {this.defaultEditors = new HashMap<>(64);// Simple editors, without parameterization capabilities.// The JDK does not contain a default editor for any of these target types.this.defaultEditors.put(Charset.class, new CharsetEditor());this.defaultEditors.put(Class.class, new ClassEditor());this.defaultEditors.put(Class[].class, new ClassArrayEditor());this.defaultEditors.put(Currency.class, new CurrencyEditor());this.defaultEditors.put(File.class, new FileEditor());this.defaultEditors.put(InputStream.class, new InputStreamEditor());this.defaultEditors.put(InputSource.class, new InputSourceEditor());this.defaultEditors.put(Locale.class, new LocaleEditor());this.defaultEditors.put(Path.class, new PathEditor());
.....}
TypeConverterDelegate 类型转换为指定类型的助手类,由BeanWrapperImpl和SimpleTypeConverter调用
内部保存了 PropertyEditorRegistrySupport
BeanUtils 对象复制、实例化、方法查找、属性描述等
ArgumentConvertingMethodInvoker 通过参数调用方法,支持重载
ArgumentConvertingMethodInvoker methodInvoker = new ArgumentConvertingMethodInvoker();
methodInvoker.setTargetClass(TestClass1.class);
methodInvoker.setTargetMethod("intArgument");
methodInvoker.setArguments(5);
methodInvoker.prepare();
methodInvoker.invoke();methodInvoker = new ArgumentConvertingMethodInvoker();
methodInvoker.setTargetClass(TestClass1.class);
methodInvoker.setTargetMethod("intArgument");
methodInvoker.setArguments(5);
methodInvoker.prepare();
methodInvoker.invoke();
PagedListHolder 将对象以分页形式展示
BeanWrapperImpl 包装指定类
BeanWrapper bw = new BeanWrapperImpl(TestBean.class);
assertThat(bw.isWritableProperty("name")).isTrue();
assertThat(bw.isWritableProperty("age")).isTrue();
CachedIntrospectionResults 缓存PropertyDescriptor,不建议应用程序使用
BeanWrapper bw = new BeanWrapperImpl(TestBean.class);
assertThat(bw.isWritableProperty("name")).isTrue();
assertThat(bw.isWritableProperty("age")).isTrue();
assertThat(CachedIntrospectionResults.strongClassCache.containsKey(TestBean.class)).isTrue();ClassLoader child = new OverridingClassLoader(getClass().getClassLoader());
Class<?> tbClass = child.loadClass("org.springframework.beans.testfixture.beans.TestBean");
assertThat(CachedIntrospectionResults.strongClassCache.containsKey(tbClass)).isFalse();
CachedIntrospectionResults.acceptClassLoader(child);
bw = new BeanWrapperImpl(tbClass);
assertThat(bw.isWritableProperty("name")).isTrue();
assertThat(bw.isWritableProperty("age")).isTrue();
assertThat(CachedIntrospectionResults.strongClassCache.containsKey(tbClass)).isTrue();
CachedIntrospectionResults.clearClassLoader(child);
assertThat(CachedIntrospectionResults.strongClassCache.containsKey(tbClass)).isFalse();assertThat(CachedIntrospectionResults.strongClassCache.containsKey(TestBean.class)).isTrue();
ExtendedBeanInfoFactory、ExtendedBeanInfo 解决链式调用问题
MutablePropertyValues PropertyValues的简单实现
TestBean target = new TestBean();
String newName = "tony";
String invalidTouchy = ".valid";
BeanWrapper accessor = createAccessor(target);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValue(new PropertyValue("age", "foobar"));
pvs.addPropertyValue(new PropertyValue("name", newName));
pvs.addPropertyValue(new PropertyValue("touchy", invalidTouchy));
assertThatExceptionOfType(PropertyBatchUpdateException.class).isThrownBy(() ->accessor.setPropertyValues(pvs)).satisfies(ex -> {assertThat(ex.getExceptionCount()).isEqualTo(2);assertThat(ex.getPropertyAccessException("touchy").getPropertyChangeEvent().getNewValue()).isEqualTo(invalidTouchy);});
// Test validly set property matches
assertThat(target.getName().equals(newName)).as("Valid set property must stick").isTrue();
assertThat(target.getAge() == 0).as("Invalid set property must retain old value").isTrue();
BeanDefinitionBuilder 构建BeanDefinition
BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(TestBean.class);
bdb.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bdb.addPropertyValue("age", "15");
for (String dependsOnEntry : dependsOn) {bdb.addDependsOn(dependsOnEntry);
}RootBeanDefinition rbd = (RootBeanDefinition) bdb.getBeanDefinition();
BeanDefinitionReaderUtils 注册bean
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, beanName);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
PropertyAccessorUtils bean属性访问
spring-aop
依赖spring-core、spring-beans
AnnotationAwareAspectJAutoProxyCreator @Aspect动态创建代理
AopProxyUtils
completeProxiedInterfaces(AdvisedSupport advised)
为代理对象添加标记接口
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
boolean addAdvised = !advised.isOpaque() && !advised.isInterfaceProxied(Advised.class);
boolean addDecoratingProxy = (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class));
spring-context
ConfigurationClassPostProcessor 扫描注解,进行注册bean
ConfigurationClassParser 解析@Configuration的注解类
ConfigurationClassEnhancer 代理增强@Configuration修饰的类,实现对@Bean发现的拦截
PostProcessorRegistrationDelegate AbstractApplicationContext的后处理器处理的委托。
StandardBeanExpressionResolver spEl表达式解析
ResourceEditorRegistrar 添加资源编码器,对URL\File等资源解析
AnnotationMetadata.introspect(class) 自省方式获取bean
AnnotationConfigUtils.attributesFor(metadata, Bean.class) 获取bean注释信息
AnnotationConfigUtils 配置了大量和注释相关的上下信息,AnnotationConfigApplicationContext回去使用
spring-webmvc
RequestMappingHandlerAdapter
afterPropertiesSet 初始mvc常用的参数解析器,初始参数解析器和返回参数解析器
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();// Annotation-based argument resolutionresolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));resolvers.add(new RequestParamMapMethodArgumentResolver());resolvers.add(new PathVariableMethodArgumentResolver());resolvers.add(new PathVariableMapMethodArgumentResolver());resolvers.add(new MatrixVariableMethodArgumentResolver());resolvers.add(new MatrixVariableMapMethodArgumentResolver());resolvers.add(new ServletModelAttributeMethodProcessor(false));resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));resolvers.add(new RequestHeaderMapMethodArgumentResolver());resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));resolvers.add(new SessionAttributeMethodArgumentResolver());resolvers.add(new RequestAttributeMethodArgumentResolver());// Type-based argument resolutionresolvers.add(new ServletRequestMethodArgumentResolver());resolvers.add(new ServletResponseMethodArgumentResolver());resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));resolvers.add(new RedirectAttributesMethodArgumentResolver());resolvers.add(new ModelMethodProcessor());resolvers.add(new MapMethodProcessor());resolvers.add(new ErrorsMethodArgumentResolver());resolvers.add(new SessionStatusMethodArgumentResolver());resolvers.add(new UriComponentsBuilderMethodArgumentResolver());// Custom argumentsif (getCustomArgumentResolvers() != null) {resolvers.addAll(getCustomArgumentResolvers());}// Catch-allresolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));resolvers.add(new ServletModelAttributeMethodProcessor(true));return resolvers;}/*** Return the list of argument resolvers to use for {@code @InitBinder}* methods including built-in and custom resolvers.*/private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();// Annotation-based argument resolutionresolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));resolvers.add(new RequestParamMapMethodArgumentResolver());resolvers.add(new PathVariableMethodArgumentResolver());resolvers.add(new PathVariableMapMethodArgumentResolver());resolvers.add(new MatrixVariableMethodArgumentResolver());resolvers.add(new MatrixVariableMapMethodArgumentResolver());resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));resolvers.add(new SessionAttributeMethodArgumentResolver());resolvers.add(new RequestAttributeMethodArgumentResolver());// Type-based argument resolutionresolvers.add(new ServletRequestMethodArgumentResolver());resolvers.add(new ServletResponseMethodArgumentResolver());// Custom argumentsif (getCustomArgumentResolvers() != null) {resolvers.addAll(getCustomArgumentResolvers());}// Catch-allresolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));return resolvers;}/*** Return the list of return value handlers to use including built-in and* custom handlers provided via {@link #setReturnValueHandlers}.*/private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();// Single-purpose return value typeshandlers.add(new ModelAndViewMethodReturnValueHandler());handlers.add(new ModelMethodProcessor());handlers.add(new ViewMethodReturnValueHandler());handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));handlers.add(new StreamingResponseBodyReturnValueHandler());handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),this.contentNegotiationManager, this.requestResponseBodyAdvice));handlers.add(new HttpHeadersReturnValueHandler());handlers.add(new CallableMethodReturnValueHandler());handlers.add(new DeferredResultMethodReturnValueHandler());handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));// Annotation-based return value typeshandlers.add(new ModelAttributeMethodProcessor(false));handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),this.contentNegotiationManager, this.requestResponseBodyAdvice));// Multi-purpose return value typeshandlers.add(new ViewNameMethodReturnValueHandler());handlers.add(new MapMethodProcessor());// Custom return value typesif (getCustomReturnValueHandlers() != null) {handlers.addAll(getCustomReturnValueHandlers());}// Catch-allif (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));}else {handlers.add(new ModelAttributeMethodProcessor(true));}return handlers;}```
## RequestMappingHandlerMapping
afterPropertiesSet -> initHandlerMethods 负责注册handelMappering