2024年java面试准备--spring篇(一)

简介: 2024年java面试准备--spring篇(一)

2024年java面试准备--spring篇


前言:Spring面试内容比较多,分成两部分整理总结,这是第一部分~~

什么是spring?

Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是控制反转(Inversion of Control,IOC)和面向切面编程(aspect-oriented programming,AOP)。

为了降低Java开发的复杂性,Spring采取了以下4种关键策略

  • 基于POJO的轻量级和最小侵入性编程;
  • 通过依赖注入和面向接口实现松耦合;
  • 基于切面和惯例进行声明式编程;
  • 通过切面和模板减少样板式代码。

反射原理以及使用场景

Java反射:

是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且都能够调用它的任意一个方法;

反射原理:

Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;其中class代表的时类对 象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组成部分。  如何得到Class的实例:

1.类名.class(就是一份字节码) 2.Class.forName(String className);根据一个类的全限定名来构建Class对象 3.每一个对象多有getClass()方法:obj.getClass();返回对象的真实类型

使用场景:

  • 开发通用框架 - 反射最重要的用途就是开发各种通用框架。很多框架(比如 Spring)都是配置化的(比如通过 XML 文件配置 JavaBean、Filter 等),为了保证框架的通用性,需要根据配置文件运行时动态加载不同的对象或类,调用不同的方法。
  • 动态代理 - 在切面编程(AOP)中,需要拦截特定的方法,通常,会选择动态代理方式。这时,就需要反射技术来实现了。
    JDK:spring默认动态代理,需要实现接口
    CGLIB:通过asm框架序列化字节流,可配置,性能差
  • 自定义注解 - 注解本身仅仅是起到标记作用,它需要利用反射机制,根据注解标记去调用注解解释器,执行行为。
  • 操作权限不够的类属性和方法

Spring框架的设计目标,设计理念,和核心是什么?

Spring设计目标:Spring为开发者提供一个一站式轻量级应用开发平台;

Spring设计理念:在JavaEE开发中,支持POJO和JavaBean开发方式,使应用面向接口开发,充分支持OO(面向对象)设计方法;Spring通过IoC容器实现对象耦合关系的管理, 并实现依赖反转,将对象之间的依赖关系交给IoC容器,实现解耦;

Spring框架的核心:IoC容器和AOP模块。通过IoC容器管理POJO对象以及他们之间的耦合关系;通过AOP以动态非侵入的方式增强服务。

IoC让相互协作的组件保持松散的耦合,而AOP编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。

Spring的优缺点是什么?

优点 ①. 方便解耦,简化开发

Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护,交给Spring管理。

②. AOP编程的支持

Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。

③. 声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无需手动编程。

④. 方便程序的测试

Spring对Junit4支持,可以通过注解方便的测试Spring程序。

⑤. 方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持(如:Struts、Hibernate、MyBatis等)。

⑥. 降低JavaEE API的使用难度

Spring对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。

缺点 Spring明明一个很轻量级的框架,却给人感觉大而全 Spring依赖反射,反射影响性能 使用门槛升高,入门Spring需要较长时间

Spring 框架中都用到了哪些设计模式?

工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例; 单例模式:Bean默认为单例模式。 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术; 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。 观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被自动更新,如Spring中listener的实现–ApplicationListener。

事务

spring事务传播机制

声明式事务虽然优于编程式事务,但也有不足,声明式事务管理的粒度是方法级别,而编程式事务是可以精确到代码块级别的。

要想实现事务管理和业务代码的抽离,就必须得用到 Spring 当中的AOP,其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,执行完目标方法之后根据执行的情况提交或者回滚。

  1. 声明式

在配置文件中设置以下6项

(1)、required

如果客户端没有事务 在bean中新起一个事务

如果客户端有事务bean 中就加进去

子事务 主事务 结果
异常 正常,并try-catch异常 均回滚
正常 异常 均回滚
正常 异常,并try-catch异常 不回滚

(2)、 requiresNew

不管客户端有没有事务服务器段都新起一个事务

如果客户端有事务就将事务挂起

子事务 主事务 结果
异常 正常,并try-catch异常 子回滚,主不回滚
正常 异常 子不回滚,主回滚
异常 正常 均回滚

(3)、supports

如果客户端没有事务服务端也没有事务

如果客户端有事务服务端就加一个事务

(4)、mandatcry

如果客户端没有事务服务端就会报错

如果客户端有事务服务端就加事务

(5)、notSupported

不管客户端有没有事务服务端都没有事务

如果客户端有事务服务端就挂起

(6)、never

不管客户端有没有事务服务端都没有事务

如果客户端有事务就报错

(7)、NESTED

如果当前存在事务,则在嵌套事务内执行。

如果当前没有事务,则进行与REQUIRED类似的操作

子事务 主事务 结果
异常 正常,并try-catch异常 子回滚,主不回滚
正常 异常 均回滚
异常 正常 均回滚
  1. 编程式事务

Javax.transaction.UserTranscation

JTA 事务可以精确到事务的开始和结束

spring事务失效原因

  1. service没有托管给spring
    失效原因: spring事务生效的前提是,service必须是一个bean对象
    解决方案: 将service注入spring
  2. 抛出受检异常
    失效原因: spring默认只会回滚非检查异常和error异常
    解决方案: 配置rollbackFor
  3. 业务自己捕获了异常(try-catch)
    失效原因: spring事务只有捕捉到了业务抛出去的异常,才能进行后续的处理,如果业务自己捕获了异常,则事务无法感知。
    解决方案: 1、将异常原样抛出;
    2、设置TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  4. 切面顺序导致
    失效原因: spring事务切面的优先级顺序最低,但如果自定义的切面优先级和他一样,且自定义的切面没有正确处理异常,则会同业务自己捕获异常的那种场景一样
    解决方案: 1、在切面中将异常原样抛出;
    2、在切面中设置TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
  5. 非Public方法
    失效原因: spring事务默认生效的方法权限都必须为public
    解决方案: 1、将方法改为public;
    2、修改TansactionAttributeSource,将publicMethodsOnly改为false
  6. 父子容器
    失效原因: 子容器扫描范围过大,将未加事务配置的serivce扫描进来
    解决方案: 1、父子容器个扫个的范围; 2、不用父子容器,所有bean都交给同一容器管理
  7. 方法用final/static修饰
    失效原因: 因为spring事务是用动态代理实现,因此如果方法使用了final修饰,则代理类无法对目标方法进行重写,植入事务功能
    解决方案: 1、方法不要用final修饰
  8. 调用本类方法
    失效原因: 本类方法不经过代理,无法进行增强
    解决方案: 1、注入自己来调用; 2、使用@EnableAspectJAutoProxy(exposeProxy = true) + AopContext.currentProxy()
  9. 多线程调用
    失效原因: 因为spring的事务是通过数据库连接来实现,而数据库连接spring是放在threadLocal里面。同一个事务,只能用同一个数据库连接。而多线程场景下,拿到的数据库连接是不一样的,即是属于不同事务
  10. 错误的传播行为
    失效原因: 使用的传播特性不支持事务
  11. 使用了不支持事务的存储引擎
    失效原因: 使用了不支持事务的存储引擎。比如mysql中的MyISAM
  12. 数据源没有配置事务管理器
    注: 因为springboot,他默认已经开启事务管理器。
  13. 被代理的类过早实例化
    失效原因: 当代理类的实例化早于AbstractAutoProxyCreator后置处理器,就无法被AbstractAutoProxyCreator后置处理器增强

Bean

Bean的生命周期

(1)默认情况下,IOC容器中bean的生命周期分为五个阶段:

  1. 调用构造器 或者是通过工厂的方式创建Bean对象
  2. 给bean对象的属性注入值
  3. 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的
  4. 使用
  5. IOC容器关闭时, 销毁Bean对象

(2)当加入了Bean的后置处理器后,IOC容器中bean的生命周期分为七个阶段:

. 调用构造器 或者是通过工厂的方式创建Bean对象

  1. 给bean对象的属性注入值
  2. 执行Bean后置处理器中的 postProcessBeforeInitialization
  3. 调用初始化方法,进行初始化, 初始化方法是通过init-method来指定的
  4. 执行Bean的后置处理器中 postProcessAfterInitialization
  5. 使用
  6. IOC容器关闭时, 销毁Bean对象

Bean作用域

名称 作用域
singleton 单例对象,默认值的作用域
prototype 每次获取都会创建⼀个新的 bean 实例
request 每⼀次HTTP请求都会产⽣⼀个新的bean,该bean仅在当前HTTP request内有效。
session 在一次 HTTP session 中,容器将返回同一个实例
global-session 将对象存入到web项目集群的session域中,若不存在集群,则global session相当于session

默认作用域是singleton,多个线程访问同一个bean时会存在线程不安全问题

2024年java面试准备--spring篇(二)https://developer.aliyun.com/article/1393088

相关文章
|
1天前
|
存储 Java
面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
43 23
|
1天前
|
监控 Java 应用服务中间件
Spring Boot 源码面试知识点
【5月更文挑战第12天】Spring Boot 是一个强大且广泛使用的框架,旨在简化 Spring 应用程序的开发过程。深入了解 Spring Boot 的源码,有助于开发者更好地使用和定制这个框架。以下是一些关键的知识点:
20 6
|
1天前
|
Java 数据安全/隐私保护 Spring
Java 中 Spring Boot 框架下的 Email 开发
Java 中 Spring Boot 框架下的 Email 开发
18 2
|
1天前
|
前端开发 Java 测试技术
Java一分钟之Spring MVC:构建Web应用
【5月更文挑战第15天】Spring MVC是Spring框架的Web应用模块,基于MVC模式实现业务、数据和UI解耦。常见问题包括:配置DispatcherServlet、Controller映射错误、视图解析未设置、Model数据传递遗漏、异常处理未配置、依赖注入缺失和忽视单元测试。解决这些问题可提升代码质量和应用性能。注意配置`web.xml`、`@RequestMapping`、`ViewResolver`、`Model`、`@ExceptionHandler`、`@Autowired`,并编写测试用例。
33 3
|
1天前
|
Java 关系型数据库 MySQL
【Java Spring开源项目】新蜂(NeeBee)商城项目运行、分析、总结
【Java Spring开源项目】新蜂(NeeBee)商城项目运行、分析、总结
12 4
|
1天前
|
消息中间件 安全 前端开发
字节面试:说说Java中的锁机制?
Java 中的锁(Locking)机制主要是为了解决多线程环境下,对共享资源并发访问时的同步和互斥控制,以确保共享资源的安全访问。 锁的作用主要体现在以下几个方面: 1. **互斥访问**:确保在任何时刻,只有一个线程能够访问特定的资源或执行特定的代码段。这防止了多个线程同时修改同一资源导致的数据不一致问题。 2. **内存可见性**:通过锁的获取和释放,可以确保在锁保护的代码块中对共享变量的修改对其他线程可见。这是因为 Java 内存模型(JMM)规定,对锁的释放会把修改过的共享变量从线程的工作内存刷新到主内存中,而获取锁时会从主内存中读取最新的共享变量值。 3. **保证原子性**:锁
16 1
|
1天前
|
移动开发 前端开发 NoSQL
ruoyi-nbcio从spring2.7.18升级springboot到3.1.7,java从java8升级到17(二)
ruoyi-nbcio从spring2.7.18升级springboot到3.1.7,java从java8升级到17(二)
48 0
|
1天前
|
JSON 前端开发 Java
【JAVA进阶篇教学】第七篇:Spring中常用注解
【JAVA进阶篇教学】第七篇:Spring中常用注解
|
1天前
|
XML Java 数据库连接
【JAVA基础篇教学】第十五篇:Java中Spring详解说明
【JAVA基础篇教学】第十五篇:Java中Spring详解说明
|
1天前
|
Java
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
21 0