首页 > 其他分享 >面试题-Spring 面试集

面试题-Spring 面试集

时间:2023-07-04 12:33:30浏览次数:45  
标签:容器 面试题 Spring 事务 面试 bean AOP 注解

Spring 面试集

基于Spring Framework 4.x 总结的常见面试题,系统学习建议还是官方文档走起:https://spring.io/projects/spring-framework#learn

一、一般问题

开发中主要使用 Spring 的什么技术 ?

  1. IOC 容器管理各层的组件
  2. 使用 AOP 配置声明式事务
  3. 整合其他框架

Spring有哪些优点?

  • 轻量级:Spring在大小和透明性方面绝对属于轻量级的,基础版本的Spring框架大约只有2MB。
  • 控制反转(IOC):Spring使用控制反转技术实现了松耦合。依赖被注入到对象,而不是创建或寻找依赖对象。
  • 面向切面编程(AOP):Spring支持面向切面编程,同时把应用的业务逻辑与系统的服务分离开来。
  • 容器:Spring包含并管理应用程序对象的配置及生命周期。
  • MVC框架:Spring的web框架是一个设计优良的web MVC框架,很好的取代了一些web框架。
  • 事务管理:Spring对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。
  • 异常处理:Spring提供一个方便的API将特定技术的异常(由JDBC, Hibernate, 或JDO抛出)转化为一致的、Unchecked异常。

Spring模块

简述 AOP 和 IOC 概念

AOP:Aspect Oriented Program, 面向(方面)切面的编程;Filter(过滤器)也是一种 AOP. AOP 是一种新的 方法论, 是对传统 OOP(Object-OrientedProgramming, 面向对象编程) 的补充. AOP 的主要编程对象是切面(aspect),而切面模块化横切关注点.可以举例通过事务说明.

IOC:Invert Of Control, 控制反转. 也称为 DI(依赖注入)其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源.作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式

二、依赖注入

IoC(Inverse of Control:控制反转)是一种设计思想,就是 将原本在程序中手动创建对象的控制权,交由Spring框架来管理。 IoC 在其他语言中也有应用,并非 Spring 特有。 IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。

将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。这样可以很大程度上简化应用的开发,把应用从复杂的依赖关系中解放出来。 IoC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。 在实际项目中一个 Service 类可能有几百甚至上千个类作为它的底层,假如我们需要实例化这个 Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把人逼疯。如果利用 IoC 的话,你只需要配置好,然后在需要的地方引用就行了,这大大增加了项目的可维护性且降低了开发难度。

什么是 Spring IOC 容器?

Spring 框架的核心是 Spring 容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。

什么是依赖注入?

依赖注入(DI,Dependency Injection)是在编译阶段尚未知所需的功能是来自哪个的类的情况下,将其他对象所依赖的功能对象实例化的模式。这就需要一种机制用来激活相应的组件以提供特定的功能,所以依赖注入是控制反转的基础。否则如果在组件不受框架控制的情况下,框架又怎么知道要创建哪个组件?

依赖注入有以下三种实现方式:

  1. 构造器注入
  2. Setter方法注入(属性注入)
  3. 接口注入

Spring 中有多少种 IOC 容器?

在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前,必须对它进行实例化。只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用

Spring 提供了两种类型的 IOC 容器实现

  • BeanFactory:IOC 容器的基本实现

  • ApplicationContext:提供了更多的高级特性,是 BeanFactory 的子接口

BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory;

无论使用何种方式, 配置文件是相同的。

BeanFactory 和 ApplicationContext 区别

BeanFactory ApplicationContext
懒加载 即时加载
它使用语法显式提供资源对象 它自己创建和管理资源对象
不支持国际化 支持国际化
不支持基于依赖的注解 支持基于依赖的注解

ApplicationContext

ApplicationContext 的主要实现类:

  • ClassPathXmlApplicationContext:从类路径下加载配置文件
  • FileSystemXmlApplicationContext: 从文件系统中加载配置文件
  • ConfigurableApplicationContext 扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext具有启动、刷新和关闭上下文的能力
  • WebApplicationContext 是专门为 WEB 应用而准备的,它允许从相对于 WEB 根目录的路径中完成初始化工作
  • ApplicationContext 在初始化上下文时就实例化所有单例的 Bean

从 IOC 容器中获取 Bean

  • 调用 ApplicationContext 的 getBean() 方法
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");
helloWorld.hello();

列举 IoC 的一些好处

  • 它将最小化应用程序中的代码量;
  • 它将使您的应用程序易于测试,因为它不需要单元测试用例中的任何单例或 JNDI 查找机制;
  • 它以最小的影响和最少的侵入机制促进松耦合;
  • 它支持即时的实例化和延迟加载服务

Spring IoC 的实现机制

Spring 中的 IoC 的实现原理就是工厂模式加反射机制,示例:

interface Fruit {
     public abstract void eat();
}
class Apple implements Fruit {
    public void eat(){
        System.out.println("Apple");
    }
}
class Orange implements Fruit {
    public void eat(){
        System.out.println("Orange");
    }
}
class Factory {
    public static Fruit getInstance(String ClassName) {
        Fruit f=null;
        try {
            f=(Fruit)Class.forName(ClassName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}
class Client {
    public static void main(String[] a) {
        Fruit f=Factory.getInstance("priv.starfish.spring.Apple");
        if(f!=null){
            f.eat();
        }
    }
}

三、Beans

什么是 Spring Beans?

  • 它们是构成用户应用程序主干的对象
  • Bean 由 Spring IoC 容器管理
  • 它们由 Spring IoC 容器实例化,配置,装配和管理
  • Bean 是基于用户提供给容器的配置元数据创建

Spring 提供了哪些配置方式?

  • 基于 xml 配置

    bean 所需的依赖项和服务在 XML 格式的配置文件中指定。这些配置文件通常包含许多 bean 定义和特定于应用程序的配置选项。它们通常以 bean 标签开头。例如:

    <bean id="studentbean" class="org.edureka.firstSpring.StudentBean">
     <property name="name" value="Edureka"></property>
    </bean>
    
  • 基于注解配置

    您可以通过在相关的类,方法或字段声明上使用注解,将 bean 配置为组件类本身,而不是使用 XML 来描述 bean 装配。默认情况下,Spring 容器中未打开注解装配。因此,您需要在使用它之前在 Spring 配置文件中启用它。例如:

    <beans>
    <context:annotation-config/>
    <!-- bean definitions go here -->
    </beans>
    
  • 基于 Java API 配置

    Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。

    1. @Bean 注解扮演与 <bean/> 元素相同的角色。

    2. @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。

例如:

@Configuration
public class StudentConfig {
    @Bean
    public StudentBean myStudent() {
        return new StudentBean();
    }
}

Spring Bean的作用域?

  • 在 Spring 中, 可以在 <bean> 元素的 scope 属性里设置 Bean 的作用域。

  • 默认情况下,Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例,整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例。该作用域被称为 singleton,它是所有 Bean 的默认作用域。

Spring 容器中的 bean 可以分为 5 个范围。所有范围的名称都是自说明的,但是为了避免混淆,还是让我们来解释一下:

  1. singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。
  2. prototype:原型范围与单例范围相反,为每一个bean请求提供一个实例。
  3. request:每次HTTP请求都会创建一个新的bean,该作用于仅适用于WebApplicationContext环境,在请求完成以后,bean会失效并被垃圾回收器回收。
  4. Session:同一个HTTP Session 共享一个bean,不同的 HTTP Session使用不同的bean。该作用于仅适用于WebApplicationContext环境,在session过期后,bean会随之失效。
  5. global-session:全局session作用域,仅仅在基于portlet的web应用中才有意义,Spring5已经没有了。Portlet是能够生成语义代码(例如:HTML)片段的小型Java Web插件。它们基于portlet容器,可以像servlet一样处理HTTP请求。但是,与 servlet 不同,每个 portlet 都有不同的会话

全局作用域与Servlet中的session作用域效果相同。

Spring bean 容器的生命周期是什么样的?

Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务。

Spring bean 容器的生命周期流程如下:

  1. Spring 容器根据配置中的 bean 定义实例化 bean;
  2. Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置;
  3. 如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName();
  4. 如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory();
  5. 与上面的类似,如果实现了其他 *.Aware接口,就调用相应的方法;
  6. 如果存在与 bean 关联的任何 BeanPostProcessors,则调用 preProcessBeforeInitialization() 方法;
  7. 如果为 bean 指定了 init 方法(<bean> 的 init-method 属性),那么将调用它;
  8. 最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法;
  9. 如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory();
  10. 如果为 bean 指定了 destroy 方法(<bean> 的 destroy-method 属性),那么将调用它

在 bean 初始化时会经历几个阶段,要与容器对 bean 生命周期的管理交互,可以实现 InitializingBeanDisposableBean 接口。容器对前者调用 afterPropertiesSet(),对后者调用 destroy(),以允许 bean 在初始化和销毁 bean 时执行某些操作。

官方不建议使用这两个接口,而是建议使用 @PostConstruct@PreDestroy,或者 XML 配置中使用 init-methoddestroy-method 属性

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {

    public void init() {
        // do some initialization work
    }
}

等价于

public class AnotherExampleBean implements InitializingBean {

    public void afterPropertiesSet() {
        // do some initialization work
    }
}

Spring Bean生命周期回调——初始化回调和销毁回调方法

实现 Bean 初始化回调和销毁回调各有三种方法,一是实现接口方法,二是在XML配置,三是使用注解

  • 使用注解 @PostConstruct@PreDestroy
  • 实现 InitializingBeanDisposableBean 接口
  • XML 中配置 init-methoddestroy-method

在一个 bean 中,如果配置了多种生命周期回调机制,会按照上边从上到下的次序调用

在 Spring 中如何配置 Bean?

Bean 的配置方式: 通过全类名 (反射)、 通过工厂方法 (静态工厂方法 & 实例工厂方法)、FactoryBean

什么是 Spring 装配

当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配,装配是创建应用对象之间协作关系的行为。 Spring 容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定在一起,同时装配 bean。

依赖注入的本质就是装配,装配是依赖注入的具体行为。

注入是实例化的过程,将创建的bean放在Spring容器中,分为属性注入(setter方式)、构造器注入

什么是bean自动装配?

Spring 容器可以自动配置相互协作 beans 之间的关联关系。这意味着 Spring 可以自动配置一个 bean 和其他协作bean 之间的关系,通过检查 BeanFactory 的内容里有没有使用< property>元素。

在Spring框架中共有5种自动装配,让我们逐一分析

  1. no:这是Spring框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在beanautowire属性里指定自动装配的模式

  2. byName:该选项可以根据bean名称设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的名称自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

  3. byType:该选项可以根据bean类型设置依赖关系。当向一个bean中自动装配一个属性时,容器将根据bean的类型自动在在配置文件中查询一个匹配的bean。如果找到的话,就装配这个属性,如果没找到的话就报错。

  4. constructor:构造器的自动装配和byType模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。

  5. autodetect:Spring首先尝试通过 constructor 使用自动装配来连接,如果它不执行,Spring 尝试通过 byType 来自动装配

自动装配有什么局限?

  • 基本数据类型的值、字符串字面量、类字面量无法使用自动装配来注入。
  • 装配依赖中若是出现匹配到多个bean(出现歧义性),装配将会失败

通过注解的方式配置bean | 什么是基于注解的容器配置

组件扫描(component scanning): Spring 能够从 classpath下自动扫描, 侦测和实例化具有特定注解的组件。

特定组件包括:

  • @Component:基本注解, 标识了一个受 Spring 管理的组件
  • @Respository:标识持久层组件
  • @Service:标识服务层(业务层)组件
  • @Controller: 标识表现层组件

对于扫描到的组件,,Spring 有默认的命名策略:使用非限定类名,,第一个字母小写。也可以在注解中通过 value 属性值标识组件的名称。

当在组件类上使用了特定的注解之后,,还需要在 Spring 的配置文件中声明 <context:component-scan>

  • base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类

  • 当需要扫描多个包时, 可以使用逗号分隔

  • 如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类,示例:

    <context:component-scan base-package="priv.starfish.front.web.controller"
    	annotation-config="true" resource-pattern="autowire/*.class"/>
    

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

默认情况下,Spring 容器中未打开注解装配。因此,要使用基于注解装配,我们必须通过配置<context:annotation-config /> 元素在 Spring 配置文件中启用它。

四、AOP

标签:容器,面试题,Spring,事务,面试,bean,AOP,注解
From: https://www.cnblogs.com/wind-xwj/p/17525446.html

相关文章

  • 面试题-SpringBoot
    概述说说SpringBoot和Spring的关系springboot我理解就是把springspringmvcspringdatajpa等等的一些常用的常用的基础框架组合起来,提供默认的配置,然后提供可插拔的设计,就是各种starter,来方便开发者使用这一系列的技术,套用官方的一句话,spring家族发展到今天,已经......
  • 2023春招面试题:Java并发相关知识
    1.基础知识回顾1.1什么是多线程?在没有线程的年代,在同一个进程中,程序的处理流程都是顺序的,下一个流程的开始必须等待上一个流程的结束,如果其中某一个流程非常耗时,那么会影响整个流程的处理时间cpu执行过程中并不是一个程序执行完之后cpu才切换,cpu时间片用完,就会切换到下个线程......
  • 【大厂面试题】说下 IO 多路复用?
    博主介绍:✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家✌......
  • 通过Spring Boot三分钟创建Spring Web项目
    SpringBoot简介接下来我们所有的Spring代码实例将会基于SpringBoot,因此我们先来了解一下SpringBoot这个大杀器。Spring早期使用XML配置的方式来配置SpringBeans之间的关系,比如AOP和依赖注入的配置。随着功能以及业务逻辑的日益复杂,应用便会伴随大量的XML配置文件以及复杂的Bean......
  • 实战项目:构建基于Spring Boot和Vue.js的金融项目分享
    学习SpringBoot和Vue.js结合的前后端分离项目可以按照以下步骤进行:掌握SpringBoot:学习SpringBoot的基本概念和核心特性,如自动配置、起步依赖、注解驱动等。了解Spring框架的基本知识,如IoC容器、AOP、MVC模式等。学习Vue.js:学习Vue.js的基本语法、指令和组件,理解Vue实例、数据绑......
  • springboot封装redission的分布式锁逻辑为注解
    场景概述使用分布式锁的时候,每次都需要使用trycatch处理方法中的逻辑。考虑是否可以这块逻辑抽离出来。实现在自定义的注解中添加属性来设置锁的等待时间、租赁时间和时间单位importjava.lang.annotation.*;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTI......
  • Spring容器获取Bean的9种方式
    1前言随着SpringBoot的普及,Spring的使用也越来越广,在某些场景下,我们无法通过注解或配置的形式直接获取到某个Bean。比如,在某一些工具类、设计模式实现中需要使用到Spring容器管理的Bean,此时就需要直接获取到对应的Bean。本文为大家整理汇总了常见的获取Bean的方式,并提供一些优......
  • SpringBoot教学资料6-SpringBoot登录注册功能实现(带简单前端)
     项目样式:      SQL:CREATETABLE`t_user`(`id`int(11)NOTNULLAUTO_INCREMENT,`username`varchar(32)NOTNULL,`password`varchar(32)NOTNULL,PRIMARYKEY(`id`),UNIQUEKEY`username`(`username`))ENGINE=InnoDBAUTO_INCR......
  • springMVC入门
    定义Controller//定义Controller//使用@Controller定义bean@ControllerpublicclassUserController{//设置当前操作的访问路径@RequestMapping("/save")//设置当前操作的返回值类型@ResponseBodypublicStringsave(){System.out.p......
  • SpringBoot SpringCloud Nacos等一些组件版本对应
    毕业版本依赖关系(推荐使用)由于SpringBoot2.4+和以下版本之间变化较大,目前企业级客户老项目相关SpringBoot版本仍停留在SpringBoot2.4以下,为了同时满足存量用户和新用户不同需求,社区以SpringBoot2.4为分界线,同时维护2.2.x和2021.x两个分支迭代。2021.x分支......