Spring常见面试题

1.Spring是什么,有哪些优点:

1.1 是什么? Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架,其核心就是管理资源组件以及依赖关系。

1.2 优点: 1.低侵入式设计,代码污染极低
     2.Spring的DI机制(依赖注入)降低了业务对象替换的复杂性,降低了组件之间的耦合性
     3.Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用
     4.Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问
     5.Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部

2.spring七大核心模块

在这里插入图片描述
Spring Core:核心类库,提供IOC服务;

Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);

Spring AOP:AOP服务;

Spring DAO:对JDBC的抽象,简化了数据访问异常的处理;

Spring ORM:对现有的ORM框架的支持;

Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传;

Spring MVC:提供面向Web应用的Model-View-Controller实现。

3.说说对IoC的理解

  控制反转是一种依赖倒置的设计原理,目的是降低使用者与资源之间的耦合,它是软件设计大师 Martin Fowler在 2004 年发表的”IoC Containers and DI pattern”(控制反转容器和依赖注入模式)提出的。这篇文章系统阐述了控制反转的思想,提出了控制反转有依赖查找和依赖注入实现方式。控制反转意味着在系统开发过程中,设计的类将交由容器去控制,而不是在类的内部去控制,类与类之间的关系将交由容器处理,一个类在需要调用另一个类时,只要调用另一个类在容器中注册的名字就可以得到这个类的实例,与传统的编程方式有了很大的不同,“不用你找,我来提供给你”,这就是控制反转的含义。
  ioc的底层设计模式采用了工厂模式,所有的 Bean 都需要注册到Bean工厂中,将其初始化和生命周期的监控交由工厂实现管理。程序员只需要按照规定的格式进行Bean开发,然后利用XML文件或注解的方式进行bean 的定义和参数配置,其他的动态生成和监控就不需要调用者完成,而是统一交给了容器进行管理。

4.说说对AOP的理解

  AOP是面向切面编程,我们知道OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分,如果在应用开发过程中,如果产生横切性问题,比如日志记录,权限验证,监控性能等,这个时候AOP就上场了,AOP是通过预编译方式或者运行期动态代理实现的一种方式,AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
  AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
(1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

5.Spring AOP中的两种动态代理方式

Spring AOP中的动态代理主要有两种方式,JDK基于接口的动态代理和CGLIB基于子类的动态代理:
  1.JDK动态代理只提供接口的代理,不支持类的代理。用Proxy类和InvocationHandler接口实现,InvocationHandler 通过重写invoke()方法反射反射调用目标类,并进行增强,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
  2.如果代理类(不能时final类)没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB是一个代码生成的类库,用Enhancer类和MethodInterceptor接口实现,重写intercept方法通过反射调用目标类,并进行增强,可以在运行时动态的生成指定类的一个子类对象。

6.BeanFactory和ApplicationContext有什么区别?

在这里插入图片描述
1.关系层面:
  BeanFactory是底层接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。ApplicationContext继承了BeanFactory接口,除了拥有BeanFactory定义过的方法还延伸了其他功能,如支持国际化、可同时加载多个配置文件、统一的资源文件访问方式、提供在监听器中注册bean的事件。
2.加载方式:
  BeanFactory懒加载,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。而ApplicationContext属于饿加载,只要容器一启动就创建所有的Bean对象。在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。但同时不可避免的是,当Bean对象较多时,创建容器的大量加载会占用很多的内存空间。
3.创建方式:
  BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader
4.注册方式
  BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。

7.Bean的生命周期

1.实例化Bean:
对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。对于ApplicationContext容器,当容器启动结束后,通过获取BeanDefinition对象中的信息,实例化所有的bean。
2.设置对象属性(依赖注入):
实例化后的对象被封装在BeanWrapper对象中,紧接着,Spring根据BeanDefinition中的信息 以及 通过BeanWrapper提供的设置属性的接口完成依赖注入。
3.处理Aware接口:
接着,Spring会检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给Bean:
①如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是Spring配置文件中Bean的id值;
②如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,传递的是Spring工厂自身。
③如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文;
4.BeanPostProcessor:
如果想对Bean进行一些自定义的处理,那么可以让Bean实现了BeanPostProcessor接口,那将会调用postProcessBeforeInitialization(Object obj, String s)方法。
5.InitializingBean 与 init-method:
如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
6.如果这个Bean实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法;由于这个方法是在Bean初始化结束时调用的,所以可以被应用于内存或缓存技术;
以上几个步骤完成后,Bean就已经被正确创建了,之后就可以使用这个Bean了。
7.DisposableBean:
当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()方法;
8.destroy-method:
最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

8.bean的作用域

1.singleton:默认,使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。
2.prototype:使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。
3.request:该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境。
4.session:该属性仅用于HTTP Session,同一个Session共享一个Bean实例。不同Session使用不同的实例。
5.global-session:该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。

9.Spring框架中的单例Beans是线程安全的么?

  Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”

10.Spring如何处理线程并发问题?

  在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
  ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。
  ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

11.Spring中涉及的设计模式
  1. 工厂模式:BeanFactory的使用
  2. 单例模式:ApplicationContext创建Bean对象
  3. 代理模式:Spring AOP 的实现使用了动态代理
  4. 模板模式:Spring中JdbcTemplate就是这种实现,JDBC的步骤是固定的,加载驱动、建立连接、执行SQL语句、访问结果记录集ResultSet、关闭资源。在这些步骤中第三四步是不固定的,所以留给客户实现,实际使用JdbcTemplate的时候只需要构建SQL就可以了这是典型的模板模式。
  5. 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。
  6. 适配器模式:在Spring的Aop中,使用Advice(通知)来增强被代理类的功能,Advice的类型有:BeforeAdvice、AfterReturningAdvice、ThreowSadvice。每种Advice都有对应的拦截器,MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor。
    各种不同类型的Interceptor,通过适配器统一对外提供接口,最终调用不同的advice来实现被代理类的增强。
12.Spring事务的实现方式

spring支持编程式事务管理和声明式事务管理两种方式:
1.编程式事务管理使用TransactionTemplate。
2.声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。具体实现方式可基本分为XML和注解的方式。

13.spring的事务传播行为:

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。
① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。‘
③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

14.Spring中的隔离级别:

① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
② ISOLATION_READ_UNCOMMITTED(读未提交):读未提交,允许另外一个事务可以看到这个事务未提交的数据,产生的问题:脏读,不可重复读,幻读。
③ ISOLATION_READ_COMMITTED(读已提交):读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新,产生的问题:不可重复读,幻读。(SQLServer、Oracle默认级别)
④ ISOLATION_REPEATABLE_READ(可重复读):可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新,产生的问题:幻读。(MySQL默认级别)
⑤ ISOLATION_SERIALIZABLE(串行化):一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。

15.Spring框架中有哪些不同类型的事件?

Spring 提供了以下5种标准的事件:

  1. 上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。
  2. 方法开始/重新开始容器时触发该事件。
  3. 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
  4. 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
  5. 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。
    如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。
16.SpringAOP中相关名词意义
  1. JoinPoint 连接点:在service中的方法都可以称为连接点
  2. PointCut 切入点:在service中的被动态代理增强过的方法称为切入点
  3. Advice 通知/增强:通知的类型:环绕通知,前置通知,后置通知,异常通知,最终通知
  4. Introduction 引介:不修改类代码的前提下,可以在运行期为类动态地添加一些方法或字段。
  5. Target 目标对象/被代理对象:传入动态代理方法参数中的变量
  6. Weaving 织入:把增强应用到目标对象来创建新的代理对象的过程
  7. Proxy 代理对象:一个类被织入增强后产生的结果代理类
  8. Aspect 切面:切入点和通知(引介)的结合
     所有的切入点都一定是连接点,但不是所有的连接点都是切入点
17.Spring通知有哪些类型?
  1. 前置通知,用于连接点操作执行前
  2. 后置通知,用于连接点操作正常执行结束后
  3. 异常通知,用于连接点操作抛异常时执行
  4. 最终通知,连接点退出时,最后一定要执行的片段
  5. 环绕通知,可以实现上面四个类型通知的所有功能。
    部分内容转自https://blog.csdn.net/a745233700/article/details/80959716,感谢大佬!!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值