面试题首页 > Spring面试题

Spring常见面试题

001Spring是什么?

Spring是一个轻量级框架,核心内容是IOC和AOP。它目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。主要包括以下七个模块(简单了解一下就行):
● Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
● Spring Core:核心类库,所有功能都依赖于该类库,提供IOC和DI服务;
● Spring AOP:AOP服务;
● Spring Web:提供了基本的面向Web的综合特性,提供对常见框架如Struts2的支持,Spring能够管理这些框架,将Spring的资源注入给框架,也能在这些框架的前后插入拦截器;
● Spring MVC:提供面向Web应用的Model-View-Controller,即MVC实现。
●  Spring DAO:对JDBC的抽象封装,简化了数据访问异常的处理,并能统一管理JDBC事务;
● Spring ORM:对现有的ORM框架的支持;

002Spring的优点是什么?

(1)Spring属于低侵入式设计,代码的污染极低;
(2)Spring的DI机制将对象之间的依赖关系交由框架处理,减低组件的耦合性;
(3)Spring提供了AOP技术,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,从而提供更好的复用。
(4)Spring对于主流的应用框架提供了集成支持。

003IOC是什么?

IOC,英文Inversion of Control的缩写,即“控制反转”,是一种设计思想。所谓控制反转就是把对象(bean)对象和维护对象(bean)之间的关系的权利转移到Sqring容器中去了(ApplicationContext.xml)而程序本身不在维护了。
什么意思呢?在javase中一个对象中使用另外的对象,就必须主动通过new指令去创建依赖对象,使用完后还需要销毁(比如Connection等),对象始终会和其他接口或类耦合起来。也就是说创建对象的时机和主动权都是由自己把控的,而 IOC 则是由专门的容器来帮忙创建对象,将所有的类都通过Spring容器中注册,当需要某个对象时,不再需要自己主动去 new 了,只需告诉Spring容器,然后让Spring容器主动给你。也就是说,对于某个具体的对象而言,以前是由自己控制它所引用对象的生命周期,而在IOC中,所有的对象都被 Spring容器控制,由 Spring 容器帮我们创建、查找及注入依赖对象,而引用对象只是被动的接受依赖对象,所以这叫控制反转。

004什么是DI?

IOC的一个重点就是在程序运行时,动态的向某个对象提供它所需要的其他对象,这一点是通过DI(Dependency Injection,依赖注入)来实现的,即应用程序在运行时依赖 IoC 容器来动态注入对象所需要的外部依赖。而 Spring 的 DI 具体就是通过反射实现注入的,反射允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性。

005IOC和DI的区别?

IOC是解决耦合问题的一种设计思想,DI是IOC的一种实现。IOC主要的实现方式有两种:依赖查找(DL),依赖注入(DI)。

006AOP是什么?应用?

AOP,称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,减少系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性。可用于权限认证、日志、事务处理。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:
JDK动态代理只提供接口的代理,不支持类的代理,因此要求被代理类实现接口。
CGLIB是通过继承的方式做的动态代理。

007静态代理与动态代理区别?

AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。静态代理与动态代理区别在于生成AOP代理对象的时机不同
(1)AspectJ是静态代理,也称为编译时增强,AOP框架会在编译阶段生成AOP代理类,并将AspectJ(切面)织入到Java字节码中,运行的时候就是增强之后的AOP对象。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。

008JDK动态代理和CGLIB动态代理区别?

① JDK动态代理只提供接口的代理,不支持类的代理,要求被代理类实现接口。JDK动态代理的核心是InvocationHandler接口和Proxy类,在获取代理对象时,使用Proxy类来动态创建目标类的代理类(即最终真正的代理类,这个类继承自Proxy并实现了我们定义的接口),当代理对象调用真实对象的方法时, InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;
② 如果被代理类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

009Spring AOP里面的术语解释?

1.连接点(Join point):指程序运行过程中所执行的方法。在Spring AOP中,一个连接点总代表一个方法的执行。 
2.切点(Pointcut):切点用于定义要对哪些Join point进行拦截。
切点分为execution方式和annotation方式。execution方式可以用路径表达式指定对哪些方法拦截,比如指定拦截add*、search*。annotation方式可以指定被哪些注解修饰的代码进行拦截。
3.通知(Advice):指要在连接点(Join Point)上执行的动作,即增强的逻辑,比如权限校验和、日志记录等。通知有各种类型,包括Around、Before、After、After returning、After throwing。
4.切面(Aspect):可以看成 Pointcut切点 和 Advice通知的结合,通知说明了干什么和什么时候干(什么时候通过方法名中的before,after,around等就能知道),而切点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。
5.目标对象(Target):包含连接点的对象,也称作被通知(Advice)的对象。 由于Spring AOP是通过动态代理实现的,所以这个对象永远是一个代理对象。
6.织入(Weaving):通过动态代理,在目标对象(Target)的方法(即连接点Join point)中执行增强逻辑(Advice)的过程。
7.引入(Introduction):添加额外的方法或者字段到被通知的类。Spring允许引入新的接口(以及对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。

010Spring通知(Advice)有哪些类型?

1. 前置通知(Before Advice):在连接点(Join point)之前执行的通知。
2. 后置通知(After Advice):当连接点退出的时候执行的通知(不论是正常返回还是异常退出)。 
3. 环绕通知(Around Advice):包围一个连接点的通知,这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也可以选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。
4. 返回后通知(AfterReturning Advice):在连接点正常完成后执行的通知(如果连接点抛出异常,则不执行)
5. 抛出异常后通知(AfterThrowing advice):在方法抛出异常退出时执行的通知

011Spring基于xml注入bean的几种方式?

● set()方法注入;
● 构造器注入:①通过index设置参数的位置;②通过type设置参数类型;
● 接口注入;(用的比较少)
注意:通过Spring创建的对象默认是单例的,如果需要创建多实例对象可以在标签后面添加一个属性scope="prototype":
<bean name="..." class="..." scope="prototype">

012Spring Bean的生命周期?

Spring Bean的生命周期只有四个阶段:实例化 Instantiation --> 属性赋值 Populate  --> 初始化 Initialization  --> 销毁 Destruction

013Spring 中的 bean 的作用域有哪些?

singleton, 也就是单例,意味着在整个Spring容器中只会存在一个Bean实例。
prototype,翻译成原型,意味着每次从IOC容器去获取指定Bean的时候,都会返回一个新的实例对象。
request, 针对每一次http请求,都会创建一个新的Bean
session,以sesssion会话为纬度,同一个session共享同一个Bean实例,不同的session产生不同的Bean实例
globalSession,针对全局session纬度,共享同一个Bean实例

014什么是Spring装配?

当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配。Spring容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定在一起,同时装配 bean。

015自动装配有哪些方式?

Spring 容器能够自动装配 bean。也就是说,可以通过检查 BeanFactory 的内容让 Spring 自动解析 bean 的协作者。 自动装配的不同模式:
no - 这是默认设置,表示没有自动装配。应使用显式 bean 引用进行装配。
byName - 它根据 bean 的名称注入对象依赖项。它匹配并装配其属性与 XML文件中由相同名称定义的 bean。
byType - 它根据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并装配属性。构造函数- 它通过调用类的构造函数来注入依赖项。它有大量的参数。
autodetect - 首先容器尝试通过构造函数使用 autowire 装配,如果不能,则尝试通过 byType 自动装配。

016Spring中的常用注解?

1)给容器注入组件注解
@Component:泛指各种组件
@Controller、@Service、@Repository都可以称为@Component。
@Controller:控制层
@Service:业务层
@Repository:数据访问层
2)注入bean的注解
@Autowired、@Inject是默认按照类型匹配的,
@Resource是按照名称匹配的,@Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用。
@Primary让spring进行自动装配的时候,默认使用首选的bean,和@Qualifier一个效果。
3)切面(AOP)相关注解
@Aspect 声明一个切面
@After 在方法执行之后执行(方法上)
@Before 在方法执行之前执行(方法上)
@Around 在方法执行之前与之后执行(方法上)
@PointCut 声明切点

017@Autowired和@Resource之间的区别?

(1) @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。
(2) @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入

018BeanFactory和ApplicationContext有什么区别?

1. BeanFactory是Spring里面最底层的接口,是最简单的容器,只提供了实例化对象和拿对象的功能;ApplicationContext是应用上下文,继承BeanFactory接口,它是Spring的一个更高级的容器,提供了更多的有用的功能。
2. 两者在装载Bean的时候,BeanFactory在启动的时候不会去实例化Bean,只有从容器中拿Bean的时候才会去实例化,因此应用启动的时候占用资源很少;而ApplicationContext在启动的时候就把所有的Bean全部实例化了。这样系统在启动的时候,可以尽早的发现系统中的配置问题, 建议web应用在启动的时候就把所有的Bean都加载了,以便让费时的操作放到系统启动中完成。 

019BeanFactory和FactoryBean的区别?

两者的区别在:前者是工厂类,简单理解成 beanName和bean对象映射关系的维护者(是个容器),提供根据beanName查询bean对象的能力;后者是工厂类,描述的是Bean对象实例化的过程,用于生成特定类型的对象。BeanFactory is a factory, FactoryBean is a bean。
FactoryBean 当你向容器注册名字为 factoryBeanName 的 FactoryBean的时候,你向容器注册的是 名字为&factoryBeanName的FactoryBean的对象,,通过factoryBeanName获取到的是 FactoryBean#getObject 返回的对象,该对象不受Spring 容器管理.
当创建Bean的过程中涉及到多个依赖对象的复杂配置(不是简单的属性注册),或者存在一定的复用性时,可以通过 FactoryBean 简化一部分实例过程,减少无关Bean的注册。例如 AbstractEntityManagerFactoryBean 相关实现。

020Redis 的持久化机制是什么?

Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制:
RDB:是Redis DataBase缩写快照,按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。
优点:
只有一个文件 dump.rdb,方便持久化。
容灾性好,一个文件可以保存到安全的磁盘。
性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单 独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
相对于数据集大时,比 AOF 的启动效率更高。
缺点:
数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数 据丢失。所以这种方式更适合数据要求不严谨的时候)
==
AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件
中,当重启Redis会重新将持久化的日志中文件恢复数据。当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复
优点:
数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录 到 aof 文件中一次。
通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一 致性问题。
AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flflushall))
缺点:
AOF 文件比 RDB 文件大,且恢复速度慢。
数据集大的时候,比 rdb 启动效率低。
 

目录

返回顶部