Spring面试题

01.Spring框架的基本理解

关键字

        核心思想IOC\AOP、作用(解耦、简化),简单描述框架组成

Spring框架

        是一款轻量级的开发框架,核心思想是IOC(控制反转)和AOP(面向切面编程)
为java应用程序开发提供组件管理服,用于组件之间的解耦,以及简化第三方JavaEE中间件技术的使用(JMS、任务调度、缓存、ORM框架),是一个基础架构型的开发框架;
Spring框架包括:

        IOC容器、 Validation数据校验、AOP面向切面编程
        Transactions事务管理、Spring JDBC、
        Spring MVC框架、以及各类第三方JavaEE中间件技术集成:

 02.Spring框架由哪些模块组成?

关键字:官方文档描述,由7个模块组成
        Spring Framework根据官方文档的描述,主要包括以下常用5个模块:
1.Core:核心模块

        包括:IOC Containe(IOC容器),Events(事件通知机制),Resources(资源加载机制)i18n(国际化),Validation(数据校验),Data Binding(数据绑定),Type Conversion(类型转换),SpEL(Spring表达式),AOP(面向切面编程)
2.Testing:测试模块
        包括:Mock objects(测试模拟对像),TestContext Framework(测试框架),Spring MVC Test(用于测试Spring MVC),WebTestclient(用于测试Webclient、Restful、Webflux等)
3.Data Access:数据访问模块
        包括:Transactions(事务管理),DAO Support:(统一的Data Access object DAO模式封装),JDBC(Spring对于JDBC的操作封装),O/R Mapping(Spring对于对象关系映射框架的封装,例如Hibernate等框架)等;
4.Web Servlet:基于Servlet的Web应用开发
        包括:Spring MVC(Spring基于Mvc模式设计封装的web框架),
WebSocket Spring集成WebSocket,WebSocket是一个服务器与客户端双向通信的技术)等;
5.Integration:企业级系统集成模块(不同系统之间的交互集成)

        包括:Remoting(Spring用于在分布式系统中进行远程服务调用的通讯框架),JMS
(Spring集成各类ava消息中间件、Java消息服务【Java Message Service】,例如ActiveMQ等),Java Email(邮件发送),Tasks Scheduling(任务调度):

 03.Spring IOC的理解

关键字:IOC名词解释,作用是解耦,使用IOC容器管理项目组件之间的耦合关系

IOC(Inversion of Control,中文释义:控制反转)是Spring框架的核心思想之一,主要
用于解耦。IOC是指将创建对象的控制权转移给Spring框架进行管理。由Spring框架根据配置
文件或注解
等方式,创建bean对象并管理各个bean对象之间的依赖关系。使对象之间形成松散耦合的关系,实现解耦
        。控制:指的是对象创建(实例化、管理)的权力
        。反转:控制权交给外部环境(Spring框架\、IOC容器)

 04.Spring IOC容器的理解

关键字:IOC容器的作用、存储形式、初始化过程

        IOC通常被理解为IOC Container容器,IOC容器其实就是一个Map,key是每个bean对
象的ID,value是bean对象本身。IOC容器负责创建bean对象管理bean的生命周期。并且根据配置好配置文件或注解,管理IOC容器中的每个bean,以及根据bean之间的依赖关系,完成bean之间的注入。

        IOC容器属于Spring Core模块,用来创建和管理Bean默认使用单例的方式将bean存储在DefaultListableBeanFactory类的beanDefinitionMap中(一个ConcurrentHashMap类型的Map集合);

        IOC容器使用ConcurrentHashMap集合存储了BeanDefinition对象,该对象封装了Spring对一个Bean所有配置信息,包括:类名,属性,构造方法参数,依赖,是否延迟加载,是否是单例等配置信息.

05. Spring DI的理解

●关键字:名词解释
●DI ( Dependecy Inject,中文释义:依赖注入)是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个| bean 对象都依赖IOC容器注入当前bean 对象所需要的另外一个bean对象。(例如在MyBatis整合Spring 时,( SqlSessionFactoryBean 依赖IOC容器注入一DataSource数据源bean ) ;

06.什么是Spring的bean 

简单来说,
Bean代表被IOC 容器管理的对象。
我们通过配置文件或注解,告诉IOC 容器帮助我们管理哪些对象。

07.将一个类声明为Bean的注解有哪些?

@Component :定义通用Bean的注解,可标注任意类为Bean 。如果-个Bean 不知道属于哪个层,可以使用@Component 注解标注。
@Repository :定义数据访问层Bean的注解。
●@Service : 定义业务层Bean的注解。
●@Controller : 定义控制器Bean的注解

 08. @Component和@Bean的区别是什么?

@Component 注解作用于,而@Bean 注解作用于方法
●@Component 通常是通过类路径扫描来实现自动扫描并完成装配Bean到Spring IOC容器中。
@Bean注解通常用于注解某个方法,通过@Bean 注解告诉了Spring IOC容器,该方法的返回值实例是一个| Bean 。

 09. @ Autowired和@ Resource的区别是什么?

@AutowiredSpring 提供的注解, @ResourceJDK提供的注解。
@Autowired 默认的注入方式为byType (按类型自动注入),@Resource 默认注入方式为byName (按名称自动注入) 。

 10. Spring框架中的常见注入方式有几种?

●关键字:整体介绍三种注入方式、分别介绍每个注入方式的细节
●Spring IOC有三种注入方式:构造注入、Setter注入、 属性注入;
构造注入:使用构造方法注入bean ;
Setter注入:使用Setter方法注入bean ;
属性注入:使用成员属性注入bean,不推荐。原因:使用私有的成员属性变量,依靠反射实
现,破坏封装
,只能依靠IOC 容器实现注入,不严谨;

11. Spring中常见的ApplicationContext实现类有哪些?

●关键字:分别介绍每种实现类或子接口
ClassPathXmlApplicationContext :根据项目类路径classpath' 下的配置文件加载bean ;
FileSystemXmlApplicationContext :根据当前磁盘的一个绝对系统文件路径下的配置文件  加载bean ;
●AnnotationConfigApplicationContext :根据读取到的注解加载bean ;
WebApplicationContext : Web 容器下按照配置文件加载bean ;

 12. BeanFactory和ApplicationContext有什么区别?

● 关键字:两者之间的关系、区别与不同、Bean的创建加载方式
●两者之间的关系:
BeanFactory和ApplicationContext 是Spring 的两大核心接口,都可以当
做Spring的容器;
●两者区别与不同:
。 BeanFactory是Spring里面最底层的接口,是IOC的核心,定义了IOC的基本功能,包含
了各种Bean 的定义、加载、实例化,依赖注入和生命周期管理等行为;
。ApplicationContext接口作为BeanFactory 接口的子接口,包含BeanFactory 所具备的
功能外,还提供了其它框架功能:继承MessageSource (支持国际化) ,资源文件访问、可以
同时加载多个配置文件、可以通过监听器管理bean的生命周期;
●Bean的创建加载方式.
。BeanFactroy 采用的是延迟加载形式来注入Bean,只有在使用到某个Bean时,才对该Bea
n进行加载实例化
。这样不能提前发现一些存在的Spring的配置问题。如果Bean的某一 个属
性没有注入,( BeanFacotry 加载后,直至第一次使用调用getBean() 方法才会抛出异常;
。ApplicationContext 是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,
我们就可以发现Spring中存在的配置错误
,这样有利于检查所依赖属性是否注入。 Applicat
ionContext启动后预载入所有的单实例Bean
,所以在运行的时候速度比较快,因为它们已经
创建好了。相对于BeanFactory ,ApplicationContext 唯一 的不足是占用内存空间, 当应
用程序配置Bean 较多时,程序启动较慢;

 13.Spring框架中的Bean的作用域

singleton:Spring只会为该bean对象只会创建唯一实例Spring中的bean默认都是单例
prototype:每次获取bean,Spring会创建一个新的bean实例;
request:每一次HTTP请求,Spring会创建一个新的bean实例;
session:不同的HTTP会话,Spring会创建不同的bean实例;

 14. Spring框架中的Bean的线程安全

●对于prototype作用域的Bean,每次都创建一 个新对象,也就是线程之间不存在Bean共享,因此
不会有线程安全问题
●对于singleton作用域的Bean,所有的线程都共享- 个单例状态的Bean,存在资源竞争,因此
是存在线程安全问题的
●解决办法:
  对于|singleton作用域的单例bean ,它的线程安全问题,常见有两种解决办法: .
        (1)在bean 中尽量避免定义可变的成员变量(用于保存数据的成员变量) ;
        (2)在类中定义一个ThreadLocal 成员变量,将需要可变的成员变量保存ThreadLocal                   中;

 15. Spring框架中的Bean生命周期

Spring Bean的生命周期总体分四个阶段:实例化=>属性注入=>初始化=>销毁
●Step1实例化Bean:根据配置文件中Bean 的定义,利用| Java Reflection 反射技术创建Bean的实例
●Step2 注入对象依赖的属性值(或对象)
●Step3处理各种Aware接口:
Spring会检测该Bean 是否实现了xxxAware 接口,通过Aware类型的接口,可以让Spring框架为当前 Bean 注入相应的内容
。如果Bean实现BeanNameAware接口,会调用它实现的setBeanName(String beanId)方
法,注入Bean的名字;
。如果Bean实现BeanClassLoaderAware 接口,调用setBeanClassLoader()方法,注入C
lassLoader对象的实例;
。如果Bean实现BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,注入
的是Spring工厂;
。如果Bean实现ApplicationContextAware接口,会调用setApplicationContext()方
法,注入Spring上下文;
●Step4执行BeanPostProcessor前置处理:如果想对Bean进行一-些自定义的前置处理, 那么可以
让Bean实现了BeanPostProcessor 接口,将会在该阶段调用postProcessBeforeInitialization(0bject obj, String s)方法。
●Step5执行InitializingBean初始化方法:如果 Bean实现了InitializingBean接口,执行afeterPropertiesSet()方法。
●Step6 执行init-method自定义初始化方法:如果 Bean在Spring配置文件中配置了init-method属性,则会自动调用其配置的初始化方法。
●Step7执行BeanPostProcessor后置处理:如果这个Bean 实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(0bject obj, String s)方法,由于这个方法是在Bean初始化结束后调用;

以上几个步骤完成后, Bean已经被正确创建,可以正常使用这个Bean了
●Step8执行DisposableBean销毁Bean: 当Bean不再需要时,会经过清理阶段,如果Bean实现
了DisposableBean 这个接口,会调用其实现的destroy() 方法执行销毁;
●Step9 执行destroy-method自定义销毁方法: 如果这个Bean的Spring配置中配置了destroy
-method属性,会自动调用其配置的自定义销毁方法。

 16. Spring框架如何解决循环依赖?

●循环依赖问题是指:类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。例如A类依赖了B类,B类依赖了C类,而最后C类又依赖了A类,这样就形成了循环依赖问题;

 17. Spring框架中有哪些注解?

用于声明Bean的注解:
。 @Component :定义通用Bean的注解,可标注任意类为Bean。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注。
@Repository : 定义数据访问层Bean的注解。
@Service :定义业务层Bean的注解。
@Controller :定义控制器Bean的注解。
用于注入的注解:
@Autowired :按类型自动注入
@Qualifier :按名称自动注入
声明配置、扫描、启用特性的注解:
@Configuration :声明配置类
@ComponentScan :组件扫描
@EnableScheduling :启用任务调度
@EnableAspectJAutoProxy :启用自动代理工厂

 18. Spring框架中用到的设计模式

●工厂模式:1 Spring 使用工厂模式,通过BeanFactory 或Applicat ionContext来创建对象;
●单例模式: Bean 默认作用域为单例,按照单例设计模式进行设计实现;
●策略模式:1 Resource 的实现类,针对不同的资源文件,实现了不同方式的资源获取策略;
●代理模式: Spring的AOP的实现依靠动态代理(JDK的反射和CGLIB) ;
●模板方法: Spring提供了JdbcTemplate , RedisTemplate 等模板对象,将相同的操作步骤进行
了封装;
●适配器模式: Spring AOP的增强或通知( Advice )使用到了适配器模式, Spring MVC中也用
到了适配器模式适配Controller ;

 19. Spring框架中AOP的基本理解

●关键字: AOP名词解释, AOP实现原理(动态代理)
AOP ( Aspect-Oriented Programming :面向切面编程):将那些与业务无关, 却为业务模块所共同调用的逻辑(例如事务处理、日志管理、 权限控制等)封装抽取成-个可重用的模块, 这个模块被命名为“切面”( Aspect ),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;
●Spring AOP 基于动态代理实现:
。如果被代理的对象,已经实现某个接口,则Spring AOP 会使用JDK Proxy (反射),基于
接口的方式
,创建代理对象( JDK动态代理的核心是InvocationHandler 接口和Prox
y类) ;
。如果被代理的对象,没有实现某个接口,就无法使用JDK Proxy 去进行代理了,这时候Spri
ngAOP会使用Cglib ,基于继承的方式,生成-一个被代理对象的子类来作为代理( Cglib动态代理的核心是MethodInterceptor 接口和Enhancer 类) ; 

 20. Spring AOP和AspectJ AOP有什么区别?

●关键字:增强方式的差异(运行时、编译时),实现方式的差异(动态代理、字节码操作)
Spring AOP已经集成了AspectJ , AspectJ 是- 个Java 技术生态系统中实现AOP编程.
思想的独立框架;| AspectJ 相比于Spring AOP功能更加强大,但是Spring AOP相对来说更
简单更容易;
Spring AOP属于运行时增强,而AspectJ 编译时增强;
Spring AOP基于动态代理( Proxying ),而AspectJ 基于字节码操作( Bytecode Manipulat
ion );

21. Spring AOP有哪些通知类型?

关键字:分别绍每种通知的实现接口,执行方式
前置通知:实现MethodBeforeAdvice 接口,在目标方法调用前,执行通知;
环绕通知:实现MethodInterceptor 接口,是一个包围目标方法的通知。环绕通知可以在方法
用前后
完成自定义的行为。
后置通知:实现AfterReturningAdvice 接口,在在目标方法调用后,执行通知(如果方法抛出异
常,则不执行通知) ;
异常通知:实现ThrowsAdvice 接口,在方法抛出异常时,执行通知;

 22. Spring管理事务的方式有几种?

编程式事务:在代码中硬编码(不推荐使用) :通过TransactionTemplate 或者TransactionM
anager手动管理事务,实际应用中很少使用,用于理解Spring事务管理。
声明式事务:在XML 配置文件或者基于注解@Transactional (推荐使用) ,通过AOP实现。

 23. Spring事务中有哪几种事务传播行为?

 事务传播行为是为了解决业务层方法之间互相调用时,产生事务问题。
当事务方法被另-一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。
事务传播行为有如下分类:
1. TransactionDefinition.PROPAGATION REQUIRED
如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。@Transactiona
1注解默认使用的事务传播行为。
2. TransactionDefinition.PROPAGATION_ REQUIRES_ NEW
创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事
务,Propagation. REQUIRES_ NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,不干扰。
3. TransactionDefinition.PROPAGATION NESTED
如果当前存在事务,则创建一一个事务作为当前事 务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition. PROPAGATION_ REQUIRED 。
4. TransactionDefinition.PROPAGATION_ MANDATORY
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory: 代表强制性)
5. TransactionDefinition.PROPAGATION SUPPORTS
如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
6. TransactionDefinition.PROPAGATION NOT. _SUPPORTED
以非事务方式运行,如果当前存在事务,则把当前事务挂起。
7. TransactionDefinition.PROPAGATION _NEVER
以非事务方式运行,如果当前存在事务,则抛出异常。

 24. Spring事务中有哪几种事务隔离级别?

1. TransactionDefinition.ISOLATION_ DEFAULT默认隔离级别
使用当前数据库的默认隔离级别,MySQL 默认采用的是可重 复读REPEATABLE_ READ隔离级别。Oracle默认采用的是读已提交| READ_ COMMITTED隔离级别.
2. TransactionDefinition.ISOLATION_ READ_ UNCOMMITTED读未提交
最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
3. TransactionDefinition.ISOLATION READ_ COMMITTED读已提交
允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
4. TransactionDefinition.ISOLATION_ REPEATABLE_ READ可重复读
对同- -字段的多次读取结果都是一致的, 除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
5. TransactionDefinition.ISOLATION SERIALIZABLE串行化
最高的隔离级别,完全服从ACID的隔离级别。 所有的事务依次逐个执行,这样事务之间就完全不
可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

25. Spring事务在什么情况下会失效?

1.数据库不支持事务

Spring事务生效的前提是所连接的数据库要支持事务,如果底层的数据库都不支持事务,则Spring
的事务肯定会失效。例如:如果使用的数据库为MySQL ,并且选用了MyISAM 存储引擎,则Spring 的事务就会失效。


2.事务方法未被Spring管理

如果事务方法所在的类没有加载到Spring IOC容器中,也就是说,事务方法所在的类没有被Spri
ng管理,则Spring 事务会失效。例如: ProductService 类上没有标注@Service 注解, Produc
t的实例没有加载到Spring IOC 容器中,就会造成updateProductStockCountById( )方法的事务
在Spring中失效。
 

3.方法没有被public修饰

如果事务所在的方法没有被public修饰,此时Spring的事务会失效,例如:虽然ProductService.上标注了@Service 注解,同时updateProductStockCountById() 方法.上标注了@Transactional(propagation = Propagation. REQUIRES_ NEW) 注解。
但是,由于updateProductStockCountById() 方法为内部的私有方法(使用private 修饰) ,那么此时updateProductstockCountById() 方法的事务在Spring 中会失效。
 

4.同一类中方法调用

如果同一个类中的两个方法分别为A和B,方法A.上没有添加事务注解,方法B. 上添加了@Transactional事务注解,方法A调用方法B,则方法B的事务会失效。例如: submitOrder() 方法和updateProductStockCountById()方法都在OrderService 类中,submitorder() 方法上没有标注事务注解,updateProductStockCountById() 方法.上标注了事务注解,submitorder() 方法调用了updat
eProductStockCountById()方法,此时,updateProductstockCountById() 方法的事务在Spring中会失效。
 

 5.未配置事务管理器

如果在项目中没有配置Spring的事务管理器,即使使用了Spring 的事务管理功能,Spring 的事务
也不会生效。例如:没有在项目的配置类中配置如~下代码。

 6.方法的事务传播类型不支持事务

如果内部方法的事务传播类型为不支持事务的传播类型,则内部方法的事务在Spring 中会失效。
例如:由于updateProductStockCountById() 方法的事务传播类型为NOT_ SUPPORTED ,不支持事务,则updateProductStockCountById()方法的事务会在Spring 中失效。

 7.不正确的捕获异常

不正确的捕获异常也会导致Spring 的事务失效。例如: updateProductStockCountById() 方法
中使用try-catch代码块捕获了异常,即使updateProductstockCountById() 方法内部会抛出异常,但也会被catch 代码块捕获到,此时updateProductStockCountById() 方法的事务会提交而不
会回滚,并且submitOrder() 方法的事务会提交而不会回滚,这就造成了Spring 事务的回滚失效问
题。

 

 8.错误的标注异常类型

如果在@Transactional注解中标注了错误的异常类型,则Spring事务的回滚会失效。例如:
在updateProductStockCountById()方法中捕获了异常,并且在异常中抛出了Exception 类型的异
常,此时,updateProductStockCountById()方法事务的回滚会失效。
为何会失效呢?这是因为Spring 中对于默认回滚的事务异常类型为Runt imeException,.上述代
码抛出的是Exception 异常。
默认情况下,Spring 事务中无法捕获到Exception 异常,所以此时updateProductstockCount
ById()方法事务的回滚会失效。

 26.谈谈对SpringMVC的理解?

首先,MVC 模式是模型( Model )、视图( View ).控制器( Controller )的简写,其核心思想是通
过将请求处理控制业务逻辑数据封装数据显示等流程节点分离的思想来组织代码。

 

 所以,MVC 是- -种设计模式,而Spring MVC是一款基于MVC设计模式思想实现的的MVC 框架,属于Spring技术栈的一部分。1 Spring MVC可以帮助我们进行更简洁的 Web 层的开发, 并且它天生与Spring 框架集成,更利于架构的设计与搭建。

 27. SpringMVC的工作原理(执行流程) ?

1.客户端(浏览器)发送请求,统一由DispatcherServlet拦截处理请求。
2. DispatcherServlet 根据请求信息调用HandlerMapping。HandlerMapping 根据| uri 去匹配查找能处理的Handler (也就是我们定义的 Controller 控制器), 并会将请求涉及到的拦
截器和Handler -起封装。
3. DispatcherServlet 调用HandlerAdapter 适配执行Handler 。
4. Handler 完成对用户请求的处理后,会返回一个ModelAndView 模型视图对象给DispatcherSe
rvlet。ModelAndView 中包含了数据模型以及相应的视图信息。Model 是返回的数据对象, View是View视图的逻辑名称。
5.ViewResolver 会根据逻辑View 名称查找并解析实际的View 视图文件,并根据DispaterServlet返回的Model 数据模型传给View 视图文件,进行渲染执行,产生响应结果。
6. DispaterServlet 负责将响应结果,输出至客户端浏览器。

 28. SpringMVC的核心组件有哪些?

●DispatcherServlet :核心处理器,负责统- 接收请求、将请求分发至不同的控制器,并负责客户端响应。
●HandlerMapping :处理器映射器,根据uri去匹配查找能处理的Handler ,并会将请求涉及
到的拦截器和Handler -起封装。
●HandlerAdapter :处理器适配器,根据HandlerMapping 找到的Handler ,适配执行对应
的Handler ;
●Handler : 请求处理器,处理实际请求的处理器。
●ViewResolver :视图解析器,根据Handler返回的逻辑视图名称,解析并渲染真正的视图文
件,并传递给DispatcherServlet 响应至客户端

29.动态代理和静态代理的区别

为什么要用代理模式?
2.1 中介隔离作用:

在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。
2.2 开闭原则,增加功能:
代理类除了是客户类和委托类的中介之外,我们还可以通过给代理类增加额外的功能来扩展委托类的功能,这样做我们只需要修改代理类而不需要再修改委托类,符合代码设计的开闭原则。
静态代理:
        静态代理是由程序员创建或特定工具自动生成源代码,在对其编译。
        在程序员运行之前,代理类.class文件就已经被创建了
动态代理:
        动态代理是在程序运行时通过反射机制动态创建的。
动态代理分为:
        基于接口的动态代理(jdk自带)
        基于子类的动态代理(第三方)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值