Spring 面试高频题
1. 什么是Spring框架
- Spring是一种支持IOC、AOP的轻量级开发框架,旨在提升开发效率和系统的可维护性。
2. 列举Spring的几大模块
(1)Core
(2)Data Access/Integration
(3)Web
(4)AOP
(5)Aspects
(6)Instrucmentation
(7)Messaging
(8)Test
3. @Controller和@RestController区别
- @Controller返回一个页面,主要应用于传统的前后端不分离项目;
- @RestController返回一个数据对象,数据对象直接以Json或XML形式写入Http响应,应用于前后端分离项目;
- @RestController=@Controller+@ResponseBody,@ResponseBody将@Controller返回的对象通过转换器转换成指定格式,写入Http响应对象的body中。
4. Spring IOC & AOP
-
IOC(控制反转)是一种设计思想,将传统在程序中手动创建对象的控制权交由Spring框架管理;IOC并非Spring特有;IOC容器是Spring实现IOC的载体;IOC容器实际上就是一个Map(key, value),里面存储着各种对象。
-
对象之间的依赖关系交由IOC容器管理,并由IOC容器完成对象的注入;IOC容器就像一个工厂,当我们需要创建一个对象的时候,只需要配置好XML配置文件/注解即可,完全不用考虑对象是如何创建出来的。
-
AOP(面向切面编程)将那些与业务无关,但为业务模块所共同调用的逻辑或责任封装起来(事务处理、日志管理),减少了代码冗余,降低了模块间的耦合;
-
Spring AOP基于动态代理;如果被代理类(委托类)实现了某个接口,则SpringAOP会使用JDK的动态代理,创建代理对象;如果没有实现接口,这时候SpringAOP会使用CGLIB创建被代理类的子类来作为代理。
5. Spring AOP和AspectJ AOP有什么区别
- Spring AOP属于运行时增强,基于动态代理(JDK、CGLIB);
- AspectJ AOP属于编译时增强,基于静态代理;
- 一般来说,前者更简单,后者比前者完整、功能强大。
6. Spring Bean的作用域
- singleton:唯一bean实例,默认都是单例的;
- prototype:每次请求都会生成一个bean实例;
- request:每次http请求都会生成一个bean实例,仅在当前request中有效;
- session:每次http请求都会生成一个bean实例,仅在当前session中有效;
- global-session:全局session作用域,仅在基于portlet的Web应用中有效,Spring随着portlet废弃随之废弃。
7. Spring中单例Bean的线程安全问题
多线程下,单例Bean存在线程安全问题,当多个线程操作同一个对象时,对这一对象的非静态成员变量的写操作会产生线程安全问题;
解决办法:创建TheadLocal成员变量,将可变成员变量保存到ThreadLocal中。
8. @Component和@Bean的区别
- @Component作用于类,@Bean作用于方法;
- @Component通过类路径扫描自动侦测以及自动装配到Bean容器;@Bean通过在此注解标识的方法中定义产生bean,@Bean告诉Spring这是某个类的实例,用的时候还给我;
- @Bean具有更强的自定义属性,在应用第三方库中的类需要装配到Bean容器时,只能通过@Bean。
9. 将一个类声明为Spring的Bean的注解有哪些
- @Component;
- @Repository,对应dao层;
- @Service,对应service层;
- @Controller,对应controller层。
10. Bean的生命周期
(1)Bean容器首先在配置文件中找到Bean的定义;
(2)利用Java反射机制实例化Bean;
(3)为实例化的Bean设置属性值;
(4)判断是否实现了BeanNameAware接口,调用setBeanName()方法;
(5)判断是否实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法;
(6)判断是否实现了BeanFactory接口,调用setBeanFactory()方法;
(7)判断是否实现了ApplicationContext接口,调用setApplicationContext()方法;
(8)判断是否加载了BeanPostProcessor相关实现类,执行postProcessorBeforeInitialization()方法;
(9)如果定义了初始化方法(配置init-method属性、实现initializingBean接口),则继续执行初始化方法;
(10)判断是否加载了BeanPostProcessor相关实现类,执行postProcessorAfterInitialization()方法;
(11)如果定义了销毁方法(配置destroy-method属性、实现DisposableBean接口),则继续执行初始化方法;
11. 谈谈对Spring MVC的理解
MVC是一种设计模式,SpringMVC是一款优秀的MVC框架,使得后台Web层开发更加简洁,很好的与Spring集成;
SpringMVC开发时,一般分为Controller层、Service层、Dao层(数据库操作)、Entity层。
12. SpringMVC的工作原理或流程
(1)客户端发送请求,直接请求到DispatcherServlet;
(2)DispatcherServlet根据请求调用HandlerMapping,解析对应的Handler;
(3)解析到对应的Handler后,由HandlerAdapter适配器处理;
(4)HandlerAdapter根据Handler调用真正的处理器处理请求;
(5)处理完业务后,返回一个ModelAndView对象,Model是数据对象,View是逻辑上的View;
(6)ViewResolver根据逻辑View查找实际的View;
(7)DispatcherServlet把返回的Model传给View,进行视图渲染;
(8)返回View给客户端。
13. Spring中用到的设计模式
(1)工厂模式:BeanFactory和ApplicationContext创建Bean;
(2)单例模式:默认Spring中的Bean都是单例的;
(3)代理模式:Spring AOP基于动态代理;
(4)适配器模式:Spring AOP的增强或者通知使用适配器模式,SpringMVC也是使用适配器模式适配Controller;
(5)观察者模式:Spring的事件驱动模型是典型应用;
(6)桥接模式:根据客户不同需求动态切换数据源;
(7)模板方法模式:相同的代码放在父类中,不同的代码放在不同的子类中,减少代码冗余;如RestTemplate、JmsTemplate、JpaTemplate。
14. Spring管理事务的方式有哪几种
(1)编程式事务;
(2)声明式事务:(a)基于xml的声明式事务、(b)基于注解的声明式事务。
15. Spring事务的隔离级别
(1)ISOLATION_DEFAULT:使用数据库的默认事务隔离级别;
(2)ISOLATION_READ_UNCOMMITTED:读未提交,最低的隔离级别,会产生脏读、不可重复读、幻读问题;
(3)ISOLATION_READ_COMMITTED:读已提交,允许读取并发事务已提交的数据,可以解决脏读,存在不可重复读、幻读问题;
(4)ISOLATION_REPEATABLE:可重复读,多次读取同一字段结果一致,除非数据是该事务本身所做修改,解决脏读、不可重复读,存在幻读问题;
(5)ISOLATION_SERIALIZABLE:序列化,最高的隔离级别,性能最差。
16. Spring事务的几种传播特性
-
支持当前事务:
(1)REQUIRED:如果当前存在事务,则加入当前事务,不存在,则创建新事务;
(2)SUPPORTS:如果当前存在事务,则加入当前事务,不存在,则以非事务方式运行;
(3)MANDATORY:如果当前存在事务,则加入当前事务,不存在,则抛出异常;
-
不支持当前事务:
(1)REQUIRES_NEW:如果当前存在事务,则挂起,不存在,则创建新事务;
(2)NOT_SUPPORTED:如果当前存在事务,则挂起,不存在,则以非事务方式运行;
(3)NEVER:如果当前存在事务,则抛出异常,不存在,则以非事务方式运行;
-
NESTED(嵌套):如果当前存在事务,则创建一个新事务嵌入当前事务,不存在,则创建新事务。
17. @Transactional(rollbackFor=)
- 当@Transactional作用于类,该类下所有的public方法都具有该类型的事务属性;当@Transactional作用于方法,会覆盖类级别的事务定义;
- 如果没有配置rollbackFor属性,只在遇到运行时异常才会回滚,配置rollbackFor=Exception.class属性后,在遇到非运行时异常也会回滚。
18. BeanFactory和Application区别
- BeanFactory
- 优点:使用懒加载,应用启动的时候占用资源少,对资源要求较高的应用比较有优势;
- 缺点:运行速度相对较慢;有可能出现空指针异常;不支持国际化;
- Application
- 优点:所有的Bean在启动时都进行了加载,运行速度快;启动的时候可以发现配置问题;
- 缺点:把费时的操作放到启动中完成,占用内存较大。
19. 构造函数注入和setter注入区别
构造函数注入 | setter注入 |
---|---|
没有部分注入 | 有部分注入 |
不会覆盖setter属性 | 会覆盖setter属性 |
任意修改都会创建一个新实例 | 任意修改不会创建新实例 |
适用于设置很多属性 | 适用于设置少量属性 |
20. 如何理解IOC和DI
- IOC(控制反转)是一种设计思想,将原本在程序中手动创建对象的控制器交由Spring容器管理;IOC并非Spring特有;IOC容器是Spring实现IOC的载体;IOC容器实际上就是一个Map<key, value>,里面存储着各种对象;
- 将对象之间的依赖关系交由IOC容器管理,由IOC容器完成对象的注入;IOC容器就像一个工厂,当我们需要创建对象的时候,只需配置和配置文件/注解即可,无需关心对象是怎么创建出来的。
- DI(依赖注入)的目的不是为了增加功能,而是为了重用;通过依赖注入机制,我们只需要简单的配置,无需代码就可指定目标的资源,完成自身的业务逻辑,不必关心资源来自何处,有谁实现。
21. 什么是Spring装配
当Bean在Spring容器中组合到一起时,被称为装配;
自动装配:
- byName:@Resource默认(隶属java)
- byType:@Autowired默认(隶属Spring)
区分使用注解时的@Autowired,上述是xml配置时使用。
22. Spring出现同名Bean怎么办
- 同一个配置文件中的同名Bean,以最上面的定义为准;
- 不同配置文件中的同名Bean,后解析的配置文件覆盖先解析的;
- 同文件中ComponentScan和@Bean的同名Bean,@Bean会生效。
23. Spring框架的事务管理有哪些优点
(1)提供了跨不同事务API的一致编程模型;
(2)支持声明式事务;
(3)很好地集成了Spring的各种数据访问抽象。
24. 什么是Spring拦截器及如何使用
当希望特定的功能应用于某些请求时,就要用到拦截器;
使用拦截器必须继承HandlerInterceptor接口,该接口有三个方法:
- preHandle:在执行实际处理程序之前调用
- postHandle:在执行完处理程序后调用
- afterCompletion:在完成请求后调用
25. 为什么要用Springboot
(1)只需要很少的配置,大多数情况使用默认配置即可;
(2)快速搭建项目,无需配置地自动整合第三方框架;
(3)可以完全不使用xml配置文件,使用注解或JavaConfig即可;
(4)内嵌Servlet容器,降低对环境地要求;
(5)提供starter,简化Maven配置。
26. Springboot如何实现对不同环境的属性配置文件支持
通过创建application-{profile}.properties文件,其中{profile}是具体的环境标识名称。
例如application-dev.properties用于开发环境,如果想要使用,在application.properties文件中添加spring.profiles.active=dev即可。
27. Springboot的核心注解是什么,由哪几个组成
@SpringbootApplication
- @SpringbootConfiguration:实现配置文件功能;
- @EnableAutoConfiguration:实现自动装配功能;
- @ComponentScan:实现扫描功能;
28. Springboot的starter是什么,工作原理
- starter可以看作是启动器,里面包含了一系列的依赖包,可以一站式集成Spring和其他技术,而不需要到处找示例代码和依赖包。
- 工作原理:在Springboot启动时,首先按照约定去读取starter的配置信息,根据配置信息对资源进行初始化,并且注入到Spring容器中。这样在Springboot启动后,就准备好了所需的资源。