• Java最新面试宝典 Spring面试题



    前言

    最新的 Java 面试题,技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linux…等等,会持续更新。

    如果对老铁有帮助,帮忙免费点个赞,谢谢你的发财手!

    1、Spring是什么?

    Spring是一个轻量级的IOC和AOP容器框架。是为Java应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。
    主要包括以下七个模块:
    Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
    Spring Core:核心类库,所有功能都依赖于该类库,提供IOC和DI服务;
    Spring AOP:面向切面服务;
    Spring Web:提供了基本的面向Web的综合特性;
    Spring MVC:提供面向Web应用的Model-View-Controller,即MVC实现。
    Spring DAO:对JDBC的抽象封装,简化了数据访问异常的处理,并能统一管理JDBC事务;
    Spring ORM:对现有的ORM框架的支持。

    2、Spring 的优点?

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

    3、什么是IOC?

    IOC,Inversion of Control,控制反转,指将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期(比如创建、销毁)和对象间的依赖关系。
    最直观的表达就是,以前创建对象的时机和主动权都是由自己把控的,如果在一个对象中使用另外的对象,就必须主动通过new指令去创建依赖对象。
    而 IOC 则是由专门的容器来帮忙创建对象,将所有的类都在Spring 容器中登记,当需要某个对象时,只需告诉 Spring 容器,然后 Spring 就会把你想要的对象主动给你。
    也就是说,控制对象生命周期的不再是引用它的对象,而是Spring容器,由 Spring 容器帮我们创建、查找和注入依赖对象,而引用对象只是被动的接受依赖对象,这叫控制反转。

    4、什么是 AOP?

    AOP即面向切面编程, 它与传统的OOP(面向对象编程) 相辅相成,支持将一些通用任务,如安全、事务、日志、权限等进行集中式管理,在 OOP 中, 我们以类(class)作为基本单元, 而 AOP 中的基本单元是Aspect(切面)。

    5、AOP 有哪些实现方式?

    实现 AOP 的技术,主要分为两大类:
    静态代理 - 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类。
    动态代理 - 分为2种:
    JDK动态代理:是通过反射机制来生成动态代理类,并且要求目标类必须实现InvocationHandler接口。
    CGLIB动态代理:如果目标类没有实现接口,那么Spring会选择使用CGLIB来动态代理。CGLIB( Code Generation Library ),是一个代码生成的类库,可以在运行时动态的生成某个类的子类。注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

    6、什么是DI依赖注入?

    在依赖注入中,我们不必创建对象,只需描述如何创建它们,我们也不必在代码中将组件和服务连接在一起,而是在配置文件描述中哪些组件需要哪些服务,由 IOC 容器将它们装配在一起。
    通常,依赖注入可以通过2种方式完成,即:
    1、构造函数注入
    2、setter 注入。

    7、将一个类声明为Spring的 bean 的注解有哪些?

    • 1、基于注解配置
      @Component ,@(Rest)Controller, @Service, @Repository,@Import
    • 2、基于配置类
      通过@Configuration和@Bean 注解
    @Configuration
    public class RedisConfig {
        @Bean
        public StudentBean myStudent() {
            return new StudentBean();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 3、基于 xml 配置
      xml配置文件包含许多 bean 定义,它们通常以 bean 标签开头。例如:
    <bean id="studentbean" class="org.edureka.firstSpring.StudentBean">
     	<property name="name" value="Edureka">property>
    bean>
    
    • 1
    • 2
    • 3

    8、区分 BeanFactory 和 ApplicationContext?

    • BeanFactory是Spring中⾮常核⼼的组件,表示Bean⼯⼚,可以⽣成和维护Bean;
    • ApplicationContext继承了BeanFactory,所以ApplicationContext拥有BeanFactory所有的特点,也是⼀个Bean⼯⼚,但是ApplicationContext除了继承BeanFactory之外,还继承了其他接口(比如EnvironmentCapable、MessageSource、ApplicationEventPublisher),因此ApplicationContext还有获取系统环境变量、国际化、事件发布等功能,这是BeanFactory所不具备的。

    9、Spring 中的 bean 的作用域有哪些?

    singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
    prototype : 每次请求都会创建一个新的 bean 实例。
    request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。
    session : :在一个HTTP Session中,一个Bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

    10、Spring 中的 bean 生命周期?

    在我理解Spring Bean的生命周期,大致分为Bean的实例化、Bean的初始化、Bean的生存期和Bean的销毁四个阶段。
    简单来说有下面几步:
    1、Spring根据我们定义的注解(@component),找到相应的类,并将定义的信息保存起来。
    2、将bean的定义发布到SpringIOC容器中,根据其实现的Aware接口设置依赖信息(主要是BeanNameAware接口(可以知道自己在容器中的名字),BeanFactoryAware(可以根据bean名称来获取Bean对象),ApplicationContextAware(可以获取Spring上下文信息))
    3、接下来调用前置初始化方法postProcessBeforeInitialization方法,完成初始化前的相关工作,比如属性填充;
    4、调用afterPropertiesSet方法,实现initialzingBean接口,去做一些初始化相关的自定义工作;
    5、调用后置初始化方法postProcessAfterInitialization方法,完成初始化后的自相关工作,比如AOP;
    6、到这里,Bean的初始化完成,就可以使用这个Bean对象了;
    7、当Bean不再用到,便要销毁。销毁过程:如果实现了DisposableBean接口,则会调用destroy方法;若配置了destry-method属性,则会调用其自定义的销毁方法。

    11、Spring启动大概流程?

    UseService.class-> 无参构造函数-> 普通对象-> 依赖注入成员属性-> 初始化(afterPropertySet)成员方法-> 初始化后(AOP)
    -> 生成代理对象-> 放入map

    12、Spring中出现同名bean怎么办?

    • 1、同一个配置文件内同名的Bean,spring会报错
    • 2、不同配置文件中存在同名Bean,后者覆盖前者
    • 3、xml配置文件和注解存在同名Bean,xml配置文件优先级高于注解。

    13、如何开启注解的依赖注入?

    要使用 @Autowired,可以有以下两种方式来实现:

    • 1、引入配置文件中的下引入 :
    • 2、在配置文件中直接引入AutowiredAnnotationBeanPostProcessor
      < bean class=“org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor”/>

    14、Spring如何解决循环依赖?

    循环依赖是指两个或多个 Bean之间互相持有对方的引用,循环依赖将会导致注入死循环。 比如:A依赖于B、B依赖于A
    而 Spring 中设计了三级缓存来解决循环依赖问题,简单的说就是:
    1、A创建过程中需要B,于是将A放到三级缓存里面,先去创建B;
    2、B创建的时候发现需要A,于是B先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A,然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A;
    3、此时B已经创建好了,将自己放到一级缓存里面(此时B里面的A依然是创建中状态),然后回来接着创建A,直接从一级缓存里面拿到B,然后A也创建好了,并将A放到一级缓存中,并删除二级缓存里的A。
    其中,一级缓存:所有的成熟bean
    二级缓存:原生的早期bean
    三级缓存:代理的bean
    Springboot可以通过@lazy注解懒加载解决。

    15、Spring中的事务是如何实现的?

    Spring事务底层是基于数据库事务和AOP机制,底层原理是这样的:

    1. ⾸先对于使⽤了@Transactional注解的Bean,Spring会创建⼀个代理对象,
      当调⽤代理对象的⽅法时,会先判断该⽅法上是否加了@Transactional注解;
    2. 如果加了,则创建⼀个数据库连接,并把它的⾃动提交(autocommit)改为false,然后放到ThreadLocal中;
    3. 如果该⽅法执行完后,没有出现异常就直接提交事务,如果出现了异常,就回滚事务。
      3、Spring事务的隔离级别和传播机制
    4. Spring事务的隔离级别对应的就是数据库的隔离级别;
    5. Spring事务的传播机制是Spring自己实现的,默认是required;
    6. Spring事务的传播机制是基于数据库连接来做的,⼀个数据库连接对应⼀个事务,如果传播机制配置为required_new,那么实际上就是新建⽴⼀个数据库连接,这两个事务是互不影响的。

    16、Spring中事务失效情况?

    1. 数据库引擎不支持事务
      mysql存储引擎除了innodb,其它都不支持事务;
    2. 类没有被spring管理
      类没有加@Component注解,这个类就不会添加到Spring容器中;
    3. 方法不是public修饰或者是final修饰
      @Transactional只能用在public方法上面,因为底层cglib动态代理是通过继承来实现的;
    4. 调用内部方法
      调用内部方法不是代理类调用;
    5. 抛出的异常被捕获
      异常被try catch 捕获,Spring事务会认为没有出现异常;
    6. 事务的传播机制配置错误
      传播机制配置为required_new或者never
    7. rollbackFor属性设置错误
      默认是RuntimeException或error回滚,比如自定义异常没有继承RuntimeException

    17、Spring事务的传播机制?

    事务的传播机制是Spring框架实现的功能,是指事务方法A,被另外一个方法B调用的时候,对方法A有何种影响:

    • PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中;
    • PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起;
    • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

    18、Spring框架中的单例bean是线程安全的吗?

    不是线程安全的,当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这时多个线程会并发执行该请求多对应的业务逻辑(成员方法)。
    可以通过ThreadLocal和线程同步机制解决共享变量问题。

    19、你用过哪些重要的Spring注解?

    @Controller -用于Spring MVC项目中的控制器类。@Service -用于服务类。
    @RequestMapping -用于在控制器处理程序方法中配置URI映射。
    @ResponseBody -用于发送Object作为响应,通常用于发送XML或JSON数据作为响应。@PathVariable -用于将动态值从URI映射到处理程序方法参数。
    @Autowired -用于在spring bean中自动装配依赖项。
    @Qualifier -使用@Autowired注解,以避免在存在多个bean类型实例时出现混淆。@Scope -用于配置spring bean的范围。
    @Configuration,@ComponentScan和@Bean -用于基于java的配置。@Aspect,@Before,@After,@Around,@Pointcut -用于切面编程(AOP)。

    20、Spring事务的实现方式和实现原理?

    Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务
    功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
    Spring支持两种类型的事务管理:
    编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
    声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。

    总结

    都已经看到这里啦,赶紧收藏起来,祝您工作顺心,生活愉快!

  • 相关阅读:
    YOLOv5算法改进(19)— 手把手教你去更换NMS(DIoU-NMS/CIoU-NMS/EIoU-NMS/GIoU-NMS/SIoU-NMS)
    pygame绘制梯形 使用polygon函数
    Postgresql源码(67)LWLock锁的内存结构与初始化
    利用扰动模型计算旋转矩阵的导数例题
    JAVA异常输出到控制台
    【数据结构】排序详解一
    LeetCode 341. 扁平化嵌套列表迭代器【设计,迭代器,DFS或栈】中等
    【软考软件评测师】第十七章 计算机组成与体系结构(总线技术)
    使用STM32控制TMC5160驱动步进电机
    基于SpringBoot的共享单车管理系统
  • 原文地址:https://blog.csdn.net/qq_42872034/article/details/136310279