说一说Spring经典面试题和自己的理解

本文参照了一部分codeSheep公众号的《Spring经典面试题汇总》,还有的就是我一部分的个人见解(用的大白话),如有不足,请指正,开始!

1.2. 什么是 Spring Framework?

这个就是个纯概念的题目,感觉说自己的理解反而显得零碎,不专业术语,我直接用书本式的概念:

  • Spring 是一个开源应用框架,旨在降低应用程序开发的复杂度。
  • 它是轻量级、松散耦合的。
  • 它具有分层体系结构,允许用户选择组件,同时还为 J2EE 应用程序开发提供了一个有凝聚力的框架。
  • 它可以集成其他框架,如 Structs、Hibernate、EJB 等,所以又称为框架的框架。

1.3. 列举 Spring Framework 的优点。

这个我就开始说了。

  • Spring Framework的核心功能是IOC、AOP,前者将创建对象的权利交由spring容器来管理,你只需要在配置文件中描述如何创建它们即可,降低了程序的耦合性;后者的定义就是“面向切面编程”,将业务与逻辑分离,进行了程序的解耦。
  • 简化了API的使用,这一点应该是最能直接感受到的,比如JDBCTemplate模板类,对原生的jdbc进行了封装,你如果写过原生的jdbc,多少应该能感觉到这个模板类带来了几行代码的便利吧。
  • 可以兼容其他框架,用户可以自行选择其他组件构成自己的框架(这估计也是他经久不衰的缘由了)。
  • 他的源码运用了大量的设计模式,无处不体现着创作者在编程上的造诣和对代码质量的苛刻,所以说这个源码很适合人们学习。
  • 使用了声明式事务,将我们从单调烦闷的事务管理代码中解脱了出来,这种声明式事务使得我们的开发效率和代码质量更加的高(好像有点印象,以前好像是编程式事务)。
  • 免费开源,哈哈,这个居然忘了。

1.4. Spring Framework 有哪些不同的功能?

这个也太明显了吧,IOC和AOP核心功能。

  • IOC,控制反转;
  • AOP,面向切面编程;
  • spring容器,负责管理bean对象的生命周期;
  • MVC,清晰的角色划分(很多组件构成了一套请求到返回视图的流程),简化了文件上传,和spring其他框架无缝集成,强大的绑定机制(可以直接接收参数绑定到pojo对象);

1.5. Spring Framework 中有多少个模块,它们分别是什么?

这个主要考的是那种图,就是那个绿色的划分了很多模块的矩形的图片。
这个说的时候就直接说Web模块,Data Access模块,AOP模块…
在这里插入图片描述

1.6. 什么是 Spring 配置文件?

这不就xml文件吗,有什么好说的,还是说一下吧。

  • Spring配置文件是XML文件,你只需要在该文件中描述如何配置以及相互引用,别的就交给spring吧,这个XML文件比较冗长,没有注解来的简便,当然了各有各的好处,如果XML文件没有好好规划编写,那么在大项目中可能比较难以管理。

2、依赖注入(Ioc)

2.1. 什么是 Spring IOC 容器?

  • IOC容器是Spring框架的核心功能之一,它负责管理对象的声明周期,它通过读取配置文件或者扫描注解的方式来进行类的实例化。

2.2. 什么是依赖注入?

个人见解:依赖注入就是你无需显式的创建对象,就是用new的方式,你只需要声明该类型的变量来接收就可以,至于这个变量在后续使用中为什么没有报NPE是因为你在配置文件中描述了如何创建它、它们,由spring容器自动的将变量和具体的实体类装配在一起。(真的大白话,感觉说这么具体有点站不稳,反而说的抽象点还不怕面试官推翻)

2.3. 可以通过多少种方式完成依赖注入?

这个简单,在spring中有如下两种方式:

  • setter
  • 构造函数

2.4. 区分构造函数注入和 setter 注入。

构造函数注入setter 注入
没有部分注入有部分注入
不会覆盖 setter 属性会覆盖 setter 属性
任意修改都会创建一个新实例任意修改不会创建一个新实例
适用于设置很多属性适用于设置少量属性

这个是原本的答案,可以放心背,毕竟大佬写的答案,不是很理解,所以就不说自己的看法了。

2.5. spring 中有多少种 IOC 容器?

  • BeanFactory - BeanFactory 就像一个包含 bean 集合的工厂类。它会在客户端要求时实例化 bean。
  • ApplicationContext - ApplicationContext 接口扩展了 BeanFactory 接口。它在 BeanFactory 基础上提供了一些额外的功能。

2.6. 区分 BeanFactory 和 ApplicationContext。

BeanFactoryApplicationContext
它使用懒加载它使用即时加载
不支持基于依赖的注解支持基于依赖的注解

还有别的区别就不说了,不能真切的感觉到的我是不会往上面写的,因为那种自己都不理解的东西此刻写了,到时候面试的时候也记不住,大脑对于不重要的东西总是习惯性的忽略,或许也是为了像JVM内存一样更好的管理空间,提高运行效率吧。

2.7. 列举 IoC 的一些好处。

  • 如上述的区别,它支持即时记载和延迟加载;
  • 明显的特点就是降低程序的耦合

2.8. Spring IoC 的实现机制。

Spring 中的 IoC 的实现原理就是工厂模式加反射机制。
它大概就是通过你给的全限定类名找到相应的类,然后反射生成实例对象,然后工厂模式返回该对象。

3、Beans

3.1. 什么是 spring bean?

  • 它们是构成用户应用程序主干的对象。
  • Bean 由 Spring IoC 容器管理。
  • 它们由 Spring IoC 容器实例化,配置(配置property,构造方法所需参数、初始化方法之类的),装配(bean之间的组合吧)和管理(管理生命周期)。
  • Bean 是基于用户提供给容器的配置元数据(XML、注解)创建。
    这些括号里的都是我额外解读的,应该是对的。

3.2. spring 提供了哪些配置方式?

  • 提供了基于XML的配置
<bean id="" class="">
  • 注解的配置。
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
  • 基于 Java API 配置
@Configuration
public class StudentConfig {
    @Bean
    public StudentBean myStudent() {
        return new StudentBean();
    }
}

3.3. spring 支持集中 bean scope?

这个也太简单了。

  • Singleton - 每个 Spring IoC 容器仅有一个单实例。
  • Prototype - 每次请求都会产生一个新的实例(这个“每次请求”的意思是每次getBean()这个操作,每次调用这个方法都会返回新的实例对象)。
  • Request - 每一次 HTTP 请求都会产生一个新的实例,并且该 bean 仅在当前 HTTP 请求内有效。
  • Session - 每一次 HTTP 请求都会产生一个新的 bean,同时该 bean 仅在当前 HTTP session 内有效。
  • Global-session - 类似于标准的 HTTP Session 作用域,不过它仅仅在基于 portlet 的 web 应用中才有意义。Portlet 规范定义了全局 Session 的概念,它被所有构成某个 portlet web 应用的各种不同的 portlet 所共享。在 global session 作用域中定义的 bean 被限定于全局 portlet Session 的生命周期范围内。如果你在 web 中使用 global session 作用域来标识 bean,那么 web 会自动当成 session 类型来使用。(这个应该是后端搭集群的意思)

仅当用户使用支持 Web 的 ApplicationContext 时,最后三个才可用。

3.4. spring bean 容器的生命周期是什么样的?

面试官就喜欢问生命周期,我记得servlet也有个生命周期,然后SpringMVC也有个从请求过来到中间经过各种“器”最后返回到客户端浏览器页面的过程,都是一步一步的,好的,下面说一下。
原版写了很多,我也看不懂,我这里就说下我自己的理解,要求不高,回答个70%够了。

  • spring读取配置文件,生成实例化bean;
  • 如果有属性需要赋值的话,使用依赖注入填充它的属性;
  • 如果存在init-method,则调用相应的初始化方法;
  • 对象被使用;
  • 如果存在destory-method,则调用相应的销毁方法;

3.5. 什么是 spring 的内部 bean?

这个也很简单。
我直接简单明了就是一个类的内部聚合了一个对象作为其成员变量。
然后在XML配置文件上相应的体现就是

<bean id="" class="">
	<property name="">
	// 内部bean
		<bean class="">
			<property name="" value=""/>
		</bean>
	</property>
</bean>

3.6. 什么是 spring 装配

答:当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配。Spring 容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定在一起,同时装配 bean。(原封不动)
可能我理解的就是,bean对象之间的组合吧,上述的内部bean不就是一种结构吗,然后spring容器负责将这两个bean组合在一起,形成这种结构,这就是装配吧。

3.7. 自动装配有哪些方式?

Spring 容器能够自动装配 bean。也就是说,可以通过检查 BeanFactory 的内容让 Spring 自动解析 bean 的协作者。
自动装配的不同模式:

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

3.8. 自动装配有什么局限?

  • 覆盖的可能性 - 您始终可以使用 和 设置指定依赖项,这将覆盖自动装配。
  • 基本元数据类型 - 简单属性(如原数据类型,字符串和类)无法自动装配。
  • 令人困惑的性质 - 总是喜欢使用明确的装配,因为自动装配不太精确。

4、注 解

4.1. 你用过哪些重要的 Spring 注解?

  • @AutoWired、@Qualifiter、@Resourece
  • @Controller、@Component、@Service、@Repository
  • @RequestMapping、@RequestBody、@RequestParam、@PathVariable、@Cookie、@ResponseBody、@Value
  • @Aspect、@Configuration、@EnabledAspectAtuoProxy、@ComponetScan、@Import、@Bean
  • @Before、@AfterReturning、@AfterThrowing、@After、@Pointcut

4.2. 如何在 spring 中启动注解装配?

在XML配置文件中添加<context:annotation-config />即可,不过我补充一下,这个
<context:annotation-config />和< context:component-scan>,前者的作用是代替四个processor处理器,分别是

  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • PersistenceAnnotationBeanPostProcessor
  • RequiredAnnotationBeanPostProcessor
    如果你要使用@Autowired、@ Resource 、@ PostConstruct、@ PreDestroy、@PersistenceContext、@Required你就要在容器中配置这几个bean对象,但是现在<context:annotation-config />一写就代替了上述四个处理器,然后你就可以大胆的使用这些注解了,但是@Controller、@Component、@Service、@Repository,他们需要用< context:component-scan>这个才扫描进容器,本身也有上述功能,所以,后者可以直接代替前者,< context:component-scan>可以代替<context:annotation-config />。

4.3. @Component, @Controller, @Repository, @Service 有何区别?

这个我个人感觉是没什么区别的,概括点来说挂上这些注解的类都属于组件,都可以被注入到IOC容器中,只不过前一个是通用的注解,后三个更语义化一些罢了。

原答案

  • @Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
  • @Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。
  • @Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。
  • @Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。

4.4. @Required 注解有什么用?

@Required 应用于 bean 属性 setter 方法。此注解仅指示必须在配置时使用 bean 定义中的显式属性值或使用自动装配填充受影响的 bean 属性。如果尚未填充受影响的 bean 属性,则容器将抛出 BeanInitializationException。(这个注解我没用过)

5、数据访问

5.1. spring DAO 有什么用?

Spring DAO 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一种统一的方式工作。这使得用户容易在持久性技术之间切换。它还允许您在编写代码时,无需考虑捕获每种技术不同的异常。

5.5. 列举 spring 支持的事务管理类型

Spring 支持两种类型的事务管理:

  • 程序化事务管理:在此过程中,在编程的帮助下管理事务。它为您提供极大的灵活性,但维护起来非常困难。
  • 声明式事务管理:在此,事务管理与业务代码分离。仅使用注解或基于 XML 的配置来管理事务。

这个我只玩过后者,将事务配置为一个通知,然后通过XML配置AOP的方式,针对于什么方法开启事务,事务的传播行为,事务的隔离级别,事务的回滚与否、超时时间等也可以进行设置;还有就是通过注解的方式@Transactional。可能这样的方式就如上所说,没有编程式的事务控制的那么细,我猜想编程式的事务的代码应该是和那些,与数据库打交道的方法的代码,冗余在一起的,诚然,这样更灵活,但事务管理与业务代码不分离,维护起来还要涉及原来的代码,不方便。

6、AOP

6.1. 什么是 AOP?

AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与 OOP( Object-Oriented Programming, 面向对象编程) 相辅相成, 提供了与 OOP 不同的抽象软件结构的视角。

在 OOP 中, 我们以类(class)作为我们的基本单元, 而 AOP 中的基本单元是 Aspect(切面)。

6.2. AOP 中的 Aspect、Advice、Pointcut、JointPoint 和 Advice 参数分别是什么?

  • Aspect,这就是一个切面类,是通知+切入点的组合,事务可以配置成一个切面,别的普通类也可以利用XML配置或者@Aspect注解成为一个切面。
  • Advice,通知,我理解的就是到达切入点之前执行的行为、操作,类似于servlet的filter过滤器或者SpringMVC的interceptor拦截器(这里不说这二者的区别),就是加一道工序嘛。
  • Pointcut,切入点,指我们要对哪些方法进行拦截、增强,没有增加的方法则不属于切入点。
  • JointPoint,这就是连接点,指那些被拦截到的点,在spring中,这些点指的是方法,因为spring只支持方法类型的连接点。
  • Advice 参数,我们可以在 advice 方法中传递参数。我们可以在切入点中使用 args() 表达式来应用于与参数模式匹配的任何方法。如果我们使用它,那么我们需要在确定参数类型的 advice 方法中使用相同的名称(原答案,这个不懂)。

6.4. 有哪些类型的通知(Advice)?

这个太简单了,直接拿过来了。

  • Before - 这些类型的 Advice 在 joinpoint 方法之前执行,并使用 @Before 注解标记进行配置。
  • After Returning - 这些类型的 Advice 在连接点方法正常执行后执行,并使用@AfterReturning 注解标记进行配置。
  • After Throwing - 这些类型的 Advice 仅在 joinpoint 方法通过抛出异常退出并使用 @AfterThrowing 注解标记配置时执行。
  • After (finally) - 这些类型的 Advice 在连接点方法之后执行,无论方法退出是正常还是异常返回,并使用 @After 注解标记进行配置。
  • Around - 这些类型的 Advice 在连接点之前和之后执行,并使用 @Around 注解标记进行配置。

6.7. Spring AOP and AspectJ AOP 有什么区别?

Spring AOP是基于动态代理实现的,而AspectJ AOP是基于静态代理实现的;
Spring AOP仅支持方法级别的PointCut,而AspectJ AOP还支持属性级别的PointCut;

6.8. 如何理解 Spring 中的代理?

代理类=通知+目标类(即要被代理、要被增加方法的类);

6.9. 什么是编织(Weaving)?

这是个专业术语,指把增强应用到目标对象来创建新的代理对象的过程。

7、MVC

7.1. Spring MVC 框架有什么用?

我的答案

  • 它可以接收客户端的请求,然后由前端控制器DispatcherServlet调用一系列处理器,像一套流水线一样,并用Mode模型填充至视图,最终返回渲染完成的视图View;
  • 它还提供了强大的数据绑定,如果前端发送的数据和后端的某个pojo的属性可以完美映射,那么只需要加个@RequestBody,就能够实现自动封装。

原答案:Spring Web MVC 框架提供 模型-视图-控制器 架构和随时可用的组件,用于开发灵活且松散耦合的 Web 应用程序。MVC 模式有助于分离应用程序的不同方面,如输入逻辑,业务逻辑和 UI 逻辑,同时在所有这些元素之间提供松散耦合。

7.2. 描述一下 DispatcherServlet 的工作流程

这个太经典了,基本上问到SpringMVC就会问到这一套工作流程,我说一下吧。
在这里插入图片描述
大体就是

  1. 客户端发送一个请求到后端;
  2. DispatcherServlet前端控制器接收该请求,但他本身并不出来吗,而是转发,调用其他控制器,这也减少了各个组件之间的耦合性;
  3. 它先转发给HandlerMapping(处理器映射器),找到相应的Handler(处理器),我理解的这个Handler就是个我们写的那个接收请求的方法;
  4. 然后这个Handler交给HandlerAdapter(处理器适配器)处理,产生ModeAndView;
  5. 然后将这个视图返回给前端控制器,前端控制器再去找视图解析器,InternelViewResolver,将逻辑视图名称转变为物理视图名称,也就是真正去找在其配置的目录下有没有名字叫这么一个view的一个页面,然后将Mode数据填充进行视图;
  6. 最后渲染好返回给前端页面;

好的,到这里基本就说完了,感谢看到这里,实在是坚持的不容易,给你点个赞,也给自己点个赞,写了这么多。我写了一些大白话,你可以选择面试时通俗易懂地讲给面试官听,但我觉得用这些大白话理解好了,然后尽量转变为稍微专业一点的术语再讲给面试官听会更好些 ,毕竟面试官更喜欢听专业术语,你别担心他听不懂啊,哈哈,理解的时候肯定是自己的通俗的语言,不过转变不了专业术语也没关系,至少我们懂了,至少合格了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值