文章目录
- 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
- 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
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() {
@Override
public 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 resolution
resolvers.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 resolution
resolvers.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 arguments
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.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 resolution
resolvers.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 resolution
resolvers.add(new ServletRequestMethodArgumentResolver());
resolvers.add(new ServletResponseMethodArgumentResolver());
// Custom arguments
if (getCustomArgumentResolvers() != null) {
resolvers.addAll(getCustomArgumentResolvers());
}
// Catch-all
resolvers.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 types
handlers.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 types
handlers.add(new ModelAttributeMethodProcessor(false));
handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
this.contentNegotiationManager, this.requestResponseBodyAdvice));
// Multi-purpose return value types
handlers.add(new ViewNameMethodReturnValueHandler());
handlers.add(new MapMethodProcessor());
// Custom return value types
if (getCustomReturnValueHandlers() != null) {
handlers.addAll(getCustomReturnValueHandlers());
}
// Catch-all
if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
}
else {
handlers.add(new ModelAttributeMethodProcessor(true));
}
return handlers;
}
```
## RequestMappingHandlerMapping
afterPropertiesSet -> initHandlerMethods 负责注册handelMappering

本文深入探讨了Spring框架的关键组成部分,包括spring-core、spring-beans、spring-aop、spring-context和spring-webmvc模块的功能和作用。从标准元数据读取到AOP代理创建,再到Web MVC请求处理,全面解析了Spring框架的底层实现和技术细节。

4517

被折叠的 条评论
为什么被折叠?



