Spring IOC、DI、AOP以及Spring MVC面试原理(3)

简介: Spring IOC、DI、AOP以及Spring MVC面试原理(3)

第二大类:


Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如BeanNameAware可以拿到BeanName,以此类推。调用时机需要注意:所有的Aware方法都是在初始化阶段之前调用的!

Aware接口众多,这里同样通过分类的方式帮助大家记忆。

Aware接口具体可以分为两组,按照执行顺序可以分为两组,如下排列顺序同样也是Aware接口的执行顺序。

Aware Group1

BeanNameAware

BeanClassLoaderAware

BeanFactoryAware


Aware Group2

EnvironmentAware

EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。

ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware) 这几个接口可能让人有点懵,实际上这几个接口可以一起记,其返回值实质上都是当前的ApplicationContext对象,因为ApplicationContext是一个复合接口。


第三大类:简单的两个生命周期接口

InitializingBean接口 对应生命周期的初始化阶段

DisposableBean接口 对应生命周期的销毁阶段


微信图片_20220128170709.png


请别再问Spring Bean的生命周期了,简书

面试官,请别再问Spring Bean的生命周期了!,CSDN


Spring Bean的作用域


image.png


Spring中所使用的设计模式

Spring设计模式的详细使用案例可以阅读这篇文章:https://blog.csdn.net/a745233700/article/details/112598471


(1)工厂模式:Spring使用工厂模式,通过BeanFactory和ApplicationContext来创建对象


(2)单例模式:Bean默认为单例模式


(3)策略模式:例如Resource的实现类,针对不同的资源文件,实现了不同方式的资源获取策略


(4)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术


(5)模板方法:可以将相同部分的代码放在父类中,而将不同的代码放入不同的子类中,用来解决代码重复的问题。比如RestTemplate, JmsTemplate, JpaTemplate


(6)适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式,Spring MVC中也是用到了适配器模式适配Controller


(7)观察者模式:Spring事件驱动模型就是观察者模式的一个经典应用。


(8)桥接模式:可以根据客户的需求能够动态切换不同的数据源。比如我们的项目需要连接多个数据库,客户在每次访问中根据需要会去访问不同的数据库


JAVA类的加载和初始化过程


1、类的加载过程
JVM将类的加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)
1)、装载:查找并加载类的二进制数据;
2)、链接:
        验证:确保被加载类的正确性,包括文件格式验证、元数据验证、 字节码验证、符号引用验证等
        准备:为类的静态变量分配内存,并将其初始化为默认值
        解析:把类中的符号引用转换为直接引用
3)、初始化:为类的静态变量赋予正确的初始值
[面试官:请你谈谈Java的类加载过程](https://blog.csdn.net/ln152315/article/details/79223441?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161805086816780274174964%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161805086816780274174964&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~hot_rank-1-79223441.first_rank_v2_pc_rank_v29&utm_term=%E7%B1%BB%E7%9A%84%E5%8A%A0%E8%BD%BD%E8%BF%87%E7%A8%8B)
2、类的初始化,类什么时候才被初始化
1)、创建类的实例,也就是new一个对象
2)、访问某个类或接口的静态变量,或者对该静态变量赋值
3)、调用类的静态方法
4)、反射(Class.forName("com.vince.Dog"))
5)、初始化一个类的子类(会首先初始化子类的父类)
6)、JVM启动时标明的启动类,即文件名和类名相同的那个类
3、类的加载
值的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的Java.lang.Class对象,用来封装类在方法区类的对象。


对象实例化的先后顺序


1.首先,初始化父类中的静态成员变量和静态代码块;
2.然后,初始化子类中的静态成员变量和静态代码块;
3.其次,初始化父类的普通成员变量和代码块,再执行父类的构造方法;
4.最后,初始化子类的普通成员变量和代码块,再执行子类的构造方法;


spring 事务的传播机制看这篇就够了

为什么会有传播机制?

spring 对事务的控制,是使用 aop 切面实现的,我们不用关心事务的开始,提交 ,回滚,只需要在方法上加 @Transactional 注解,这时候就有问题了。


场景一: serviceA 方法调用了 serviceB 方法,但两个方法都有事务,这个时候如果 serviceB 方法异常,是让 serviceB 方法提交,还是两个一起回滚。

场景二:serviceA 方法调用了 serviceB 方法,但是只有 serviceA 方法加了事务,是否把 serviceB 也加入 serviceA 的事务,如果 serviceB 异常,是否回滚 serviceA 。

场景三:serviceA 方法调用了 serviceB 方法,两者都有事务,serviceB 已经正常执行完,但 serviceA 异常,是否需要回滚 serviceB 的数据。


传播机制生效条件

因为 spring 是使用 aop 来代理事务控制 ,是针对于接口或类的,所以在同一个 service 类中两个方法的调用,传播机制是不生效的


传播机制类型

下面的类型都是针对于被调用方法来说的,理解起来要想象成两个 service 方法的调用才可以。


PROPAGATION_REQUIRED (默认)


支持当前事务,如果当前没有事务,则新建事务

如果当前存在事务,则加入当前事务,合并成一个事务

REQUIRES_NEW


新建事务,如果当前存在事务,则把当前事务挂起

这个方法会独立提交事务,不受调用者的事务影响,父级异常,它也是正常提交

NESTED


如果当前存在事务,它将会成为父级事务的一个子事务,方法结束后并没有提交,只有等父事务结束才提交

如果当前没有事务,则新建事务

如果它异常,父级可以捕获它的异常而不进行回滚,正常提交

但如果父级异常,它必然回滚,这就是和 REQUIRES_NEW 的区别

SUPPORTS


如果当前存在事务,则加入事务

如果当前不存在事务,则以非事务方式运行,这个和不写没区别

NOT_SUPPORTED


以非事务方式运行

如果当前存在事务,则把当前事务挂起

MANDATORY


如果当前存在事务,则运行在当前事务中

如果当前无事务,则抛出异常,也即父级方法必须有事务

NEVER


以非事务方式运行,如果当前存在事务,则抛出异常,即父级方法必须无事务

一点小说明

一般用得比较多的是 PROPAGATION_REQUIRED , REQUIRES_NEW;

REQUIRES_NEW 一般用在子方法需要单独事务,暂时找不到例子,以后补充 。


spring 事务的传播机制看这篇就够了


死锁产生的四个必要条件

•互斥条件:资源是独占的且排他使用,进程互斥使用资源,即任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请者等待直到资源被占有者释放。

•不可剥夺条件:进程所获得的资源在未使用完毕之前,不被其他进程强行剥夺,而只能由获得该资源的进程资源释放。

•请求和保持条件:进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。

•循环等待条件::若干进程之间形成一种头尾相接的循环等待资源关系。

以上给出了导致死锁的四个必要条件,只要系统发生死锁则以上四个条件至少有一个成立。事实上循环等待的成立蕴含了前三个条件的成立,似乎没有必要列出然而考虑这些条件对死锁的预防是有利的,因为可以通过破坏四个条件中的任何一个来预防死锁的发生。


目录
相关文章
|
10天前
|
设计模式 前端开发 Java
步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
24 4
|
26天前
|
监控 安全 Java
什么是AOP?如何与Spring Boot一起使用?
什么是AOP?如何与Spring Boot一起使用?
53 5
|
1月前
|
Java 开发者 Spring
Spring AOP 底层原理技术分享
Spring AOP(面向切面编程)是Spring框架中一个强大的功能,它允许开发者在不修改业务逻辑代码的情况下,增加额外的功能,如日志记录、事务管理等。本文将深入探讨Spring AOP的底层原理,包括其核心概念、实现方式以及如何与Spring框架协同工作。
|
28天前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
107 2
|
1月前
|
XML 监控 安全
深入调查研究Spring AOP
【11月更文挑战第15天】
44 5
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
63 4
|
2月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
93 2