关于Spring、SpringMVC、SpringBoot面试高频问题
Spring的优点
- 方便解耦,简化开发
- AOP编程的支持
- 事务管理
- 方便调试
- 方便集成各种优秀的框架
1.Spring,MVC,SpringBoot的区别(简单介绍下Spring,MVC,SpringBoot)
最简练的语言概括就是:
Spring 是一个“引擎”;Spring MVC 是基于Spring的一个 MVC 框架;Spring Boot 是基于Spring4的条件注册的一套快速开发整合包。
Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring 的ioc和 aop。在此两者的基础上实现了其他延伸产品的高级功能。
SpringMVC 提供了一种轻度耦合的方式来开发web应用。它是Spring的一个模块,是一个web框架。使用MVC模式,使得开发web应用变得很容易。
Spring Boot
实现了自动配置,降低了项目搭建的复杂度。它主要是为了解决使用Spring框架需要进行大量的配置太麻烦的问题,它并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。
2.SpringBoot简化了哪些操作
第一点就是spring的依赖设置很繁琐,原来你导入相关的依赖坐标,可能会产生版本冲突的问题,但是现在springboot已经将版本控制好了,你不用担心版本会产生冲突。
第二点就是spring的配置很繁琐,原来的spring配置bean,配置springmvc,配置web.xml,配置tomcat等等一系列的配置,现在springboot都把这些已经配置好了,都不需要你配置了。
3.延申问题:SpringBoot如何简化(自动配置原理)(SpringBoot启动过程)
Spring Boot的启动类上有一个@SpringBootApplication注解,@SpringBootApplication是一个复合注解或派生注解,在@SpringBootApplication中有一个注解@EnableAutoConfiguration,是用来开启自动配置的。而这个注解也是一个派生注解,其中的关键功能由@Import提供,其导入的AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有具有META-INF/spring.factories 的jar包。spring.factories文件也是一组一组的key=value的形式,其中一个key是EnableAutoConfiguration类的全类名,而它的value是一个xxxxAutoConfiguration的类名的列表。这个@EnableAutoConfiguration注解通过@SpringBootApplication被间接的标记在了Spring Boot的启动类上。在SpringApplication.run(…)的内部就会执行selectImports()方法,找到所有JavaConfig自动配置类的全限定名对应的class,然后将所有自动配置类加载到Spring容器中。
4.SpringMVC启动流程
1、 用户向服务端发送一次请求,这个请求会先到前端控制器DispatcherServlet(也叫中央控制器)。
2、DispatcherServlet接收到请求后会调用HandlerMapping处理器映射器。由此得知,该请求该由哪个Controller来处理(并未调用Controller,只是得知)
3、DispatcherServlet调用HandlerAdapter处理器适配器,告诉处理器适配器应该要去执行哪个Controller
4、HandlerAdapter处理器适配器去执行Controller并得到ModelAndView(数据和视图),并层层返回给DispatcherServlet
5、DispatcherServlet将ModelAndView交给ViewReslover视图解析器解析,然后返回真正的视图。
6、DispatcherServlet将模型数据填充到视图中
7、DispatcherServlet将结果响应给用户
5.Spring 上下文类型
- AnnotationConfigApplicationContext 从Java配置类加载Spring应用上下文
- AnnotationConfigWebApplicationContext 从Java配置类加载Spring web应用上下文
- ClassPathXmlApplicationContext 从类路径下xml配置文件中加载上下文
- FilePathXmlApplicationContext 从文件系统路径下xml配置文件中加载上下文
- webXmlApplicationContext 从web应用的xml配置文件中加载上下文
//类路径下xml格式的配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(xml.url);
//磁盘路径下xml文件配置
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext();
//基于注解、java配置类的方式创建
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//基于java配置类、用于web环境创建
AnnotationConfigServletWebApplicationContext context = new AnnotationConfigServletWebApplicationContext();
6.ApplicationContext&BeanFactory关系
BeanFactory:
是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能;
ApplicationContext:
应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能;
ApplicationContext扩展方法
- getMessage(),处理国际化信息,可以翻译信息
- getResource(url),获取资源
- getEnviroment(),获取环境变量,配置信息(包括yml文件)
- publishEvent(Event对象),发布事件
BeanFactory不会主动做的事:(解析见下面源码)
- 不会主动调用beanfactory后处理器
- 不会主动添加bean后处理器
- 不会主动实例化bean
- 不会解析#{}、${};
两种容器实现详解
BeanFactory
//测试类
class Bean1{
private String name;
public Bean1(){
this.name="bean1";
}
}
class Bean2{
private String name;
public Bean2(){
this.name="bean2";
}
}
@Configuration
class Config{
@Bean
public Bean1 bean1(){
return new Bean1();
}
@Bean
public Bean2 bean2(){
return new Bean2();
}
}
不能解析注解bean
//创建beanfactory
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//bean的定义创建
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
// bean的注册,注册到beanfactory中
beanFactory.registerBeanDefinition("config",beanDefinition);
/*
config自定义bean
*/
beanfactory功能扩展(扫描config类)
//为beanfactory添加后处理器,实现功能扩展
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
/*
config自定义bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
*/
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> {
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});
/*
config自定义bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
bean1
bean2
*/
//bean后处理器,针对bean的生命周期进行扩展,例如@Autowired
beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream().forEach(beanFactory::addBeanPostProcessor);
//定义容器实例化bean的时机,默认是使用时初始化
beanFactory.preInstantiateSingletons();//提前实例化单例
7.Springboot配置文件方式:
- 在application.properites文件中{形式:server.port = 80}
- 创建appliocation.yml文件中{形式:server:port:80} 主流格式
- 创建appliocation.yaml文件中{形式:server:port:80}
8.Springboot配置文件优先级(官网给出了更多文件优先级,详情见官网)
properties>yml>yaml
9.Spring AOP五种通知类型
- 前置通知@Before()
- 后置通知@After()
- 环绕通知@Around() //方法需要传参指定何时使用原始方法 ProceedingJoinPoint ptg ptg.proceed()代表原始方法
- 返回后通知(了解)@AfterReturning
- 抛出异常后通知(了解)@AfterThrowing
10.静态代理和动态代理
静态代理:静态代理就是指我们在给一个类扩展功能的时候,我们需要去书写一个静态的类,相当于在之前的类上套了一层,这样我们就可以在不改变之前的类的前提下去对原有功能进行扩展。
实现方式:静态代理通过一个代理类与被代理对象使用同一个接口(保证方法名相同),然后在代理类里通过组合的相识,吧需要被代理的对象传入,重写的对象中调用被代理对象的方法即可实现。
缺点:若有大量的类需要被代理,则会增大代码量。
动态代理:动态代理简单来说就是在程序执行过程中,创建代理对象,通过代理对象执行方法,给目标类的方法增加额外的功能,也叫做功能增强。
11.动态代理
Jdk动态代理
JDK动态代理主要由JDK提供的Proxy实现。动态代理类是在运行时生成指定接口的代理类,每个代理实例都有一个关联的调用处理程序对象,此对象实现InvocationHandler。
最终的业务逻辑是在InvocationHandler的invoke方法中实现。
CGLIB动态代理
CGLIB动态代理主要通过对字节码的操作,为对象引入间接级别,以控制对象的访问。