面试题--框架篇
SpringMVC的工作流程?
具体的流程:
- 用户通过浏览器发起 HttpRequest 请求到
前端控制器 (DispatcherServlet)
。- DispatcherServlet 将用户请求发送给
处理器映射器 (HandlerMapping)
。- 处理器映射器 (HandlerMapping)会根据请求,找到负责处理该请求的处理器,并将其封装为处理器执行链 返回 (HandlerExecutionChain) 给 DispatcherServlet。
- DispatcherServlet 会根据 处理器执行链 中的处理器,找到能够执行该处理器的
处理器适配器(HandlerAdaptor)
--注,处理器适配器有多个。- 处理器适配器 (HandlerAdaptoer) 会调用对应的具体的
Controller
。- Controller 将处理结果及要跳转的视图封装到一个对象 ModelAndView 中并将其返回给处理器适配器 (HandlerAdaptor)
- HandlerAdaptor 直接将 ModelAndView 交给 DispatcherServlet ,至此,业务处理完毕。
- 业务处理完毕后,我们需要将处理结果展示给用户。于是DisptcherServlet 调用 ViewResolver,将 ModelAndView 中的视图名称封装为视图对象。
ViewResolver
将封装好的视图 (View) 对象返回给 DIspatcherServlet。- DispatcherServlet 调用视图对象,让其自己 (View) 进行渲染(将模型数据填充至视图中),形成响应对象 (HttpResponse)。
- 前端控制器 (DispatcherServlet) 响应 (HttpResponse) 给浏览器,展示在页面上。
SpringBoot框架特点?
springboot是全新一代的 spring 框架,其设计的目的是为了:
- 简化基于spring应用开发的配置。
- 提供自动配置的
starter
以简化 Maven 配置,减少依赖包的版本冲突。 - 内嵌 Tomcat 或 Jetty 等 Servlet 容器。
- 更轻量级。
SpringBoot框架重要的策略?
SpringBoot 框架中还有两个非常重要的策略:开箱即用
和约定优于配置
。
- 开箱即用:是指在开发过程中,通过在 MAVEN 项目的 pom 文件中添加相关依赖包,然后使用对应注解来代替繁琐的 XML 配置文件以管理对象的生命周期。这个特点使得开发人员摆脱了复杂的配置工作以及依赖的管理工作,更加专注于业务逻辑。
- 约定优于配置:是一种由 SpringBoot 本身来配置目标结构,由开发者在结构中添加信息的软件设计范式。减少了大量的XML配置,并且可以将代码编译、测试和打包等工作自动化。
springboot自动装配的原理?
@SpringBootApplication
其实是由@SpringBootConfiguration
、@EnableAutoConfiguration
、@ComponentScan
这三个注解构成的一个组合注解。
@SpringBootConfiguration
:就是一个@Configuration
注解,告诉 spring 这是一个配置类可以被加载到 spring IOC 容器中。@ComponentScan
:该注解是用于组件扫描的。自动扫描并加载符合条件的组件或者 bean 定义,最终将这些 bean 定义加载到 IoC 容器中。通过 basePackages 定制扫描路径。@EnableAutoConfiguration
:自动配置。借助@Import
的支持,收集和注册特定场景相关的 bean 定义。这其中,最关键的要属 @Import(EnableAutoConfigurationImportSelector.class),借助EnableAutoConfigurationImportSelector
,@EnableAutoConfiguration 可以帮助 SpringBoot 应用将所有符合条件的 @Configuration 配置类都加载到当前 SpringBoot 的 IoC容器。借助于Spring框架原有的一个工具类:SpringFactoriesLoader
的支持,@EnableAutoConfiguration 可以智能的自动配置功效才得以大功告成!
@Import 注解导入方式有四种:
- 导入配置类
- 导入前置加载带有 @Configuration 的配置类
- 通过ImportSelector 方式导入的类:返回需要导入的配置类的数组
- 通过ImportBeanDefinitionRegistrar 方式导入的类:返回需要导入配置类集合的注册器。
详见@Import注解的作用
Spring框架提供的各种名字为@Enable开头的Annotation定义?比如@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和做事方式其实一脉相承,简单概括一下就是,借助@Import的支持,收集和注册特定场景相关的bean定义。
@EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器。
@EnableMBeanExport是通过@Import将JMX相关的bean定义加载到IoC容器。
而@EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器,仅此而已!
@EnableAutoConfiguration会根据类路径中的jar依赖为项目进行自动配置,如:添加了spring-boot-starter-web依赖,会自动添加Tomcat和Spring MVC的依赖,Spring Boot会对Tomcat和Spring MVC进行自动配置。
上面我们说到SpringFactoriesLoader,才是 Springboot 自动配置的幕后工作者。通过上面的源码以及注释,我们会发现后一个很重要的点就是,SpringFactoriesLoader 是通过加载启动器中 META-INF/spring.factories
文件来实现自动配置的。
我们那打开一个启动器看看这当中是否有spring.factories这个文件。
META-INF/spring.factories:
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
# Auto Configuration Import Listeners
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener
# Auto Configuration Import Filters
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnClassCondition
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
...
我们能看到spring.factories文件里面都是定义了一些类的全路径,有了类的全路径我们并可以实例化这些类,再通过spring4.0基于Java的配置方式并可以实现自动配置了。
xxxxAntoConfgiration里有些什么?以HttpEncodingAutoConfiguration为例:
//表明这是一个配置类,和以前的配置类一样,可以向容器中添加组件
@Configuration(proxyBeanMethods = false)
//与ServerProperties类绑定,从这个类中获取对应的属性
@EnableConfigurationProperties(ServerProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
private final Encoding properties;
public HttpEncodingAutoConfiguration(ServerProperties properties) {
this.properties = properties.getServlet().getEncoding();
}
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
...
}
...
}}}
1.@ConditionOnxxxx(),和一些组件(用@Bean修饰的类或方法),组件上也有@ConditionOnxxxx(),@ConditionOnxxxx的意思是当所有条件满足时,他标注的类或者组件才会生效。
2.@EnableConfigurationProperties(xxxxProperties.class),意思是与xxxxProperties类绑定,当组件生效时从这个类中获取对应的属性, xxxxProperties类中有我们所有可以配置的属性,@ConfigurationProperties(prefix = “xxxx”,) public class xxxxProperties {可以配置的属性},当我们在我们的配置文件中加上对应的prefix时,我们就可以配置这个properties类中的属性了。
这就是为什么我们在我们的yml文件中配置相应的属性就可以生效的原因
对应的ServerProperties:
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {...}