Spring相关的面试题

1、spring中bean的生命周期

spring bean的生命周期主要分为三大类 ,分别是创建-》使用-〉销毁。

在三大类下面又可以分为5个小类。分别是  实列化-〉初始化-》组册destruction回调-〉使用-〉销毁

这这其中 初始化也可以细分为 设置属性值,前置处理,后置处理 这些

1. 实例化Bean:
•Spring容器首先创建Bean实例。
 在AbstractAutowireCapableBeanFactory类中的createBeanlnstance方法中实现
2. 设置属性值:
 Spring容器注入必要的属性到Bean中。
•在AbstractAutowireCapableBeanFactory的populateBean方法中处理
3. 检查Aware:
如果Bean实现了BeanNameAware、BeanClassLoaderAware等这些Aware接口,Spring容器会调用它们。
在AbstractAutowireCapableBeanFactory的initializeBean方法中调用
4. 调用BeanPostProcessor的前置处理方法:
在Bean初始化之前,允许自定义的BeanPostProcessor对Bean实例进行处理,如修改Bean的状态。BeanPostProcessor的postProcessBeforelnitialization方法会在此时被调用。
由AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsBeforelnitialization方法执行。
5. 调用InitializingBean的afterPropertiesSet方法:
提供一个机会,在所有Bean属性设置完成后进行初始化操作。如果Bean实现了InitializingBean接口,afterPropertiesSet方法会被调用。
在AbstractAutowireCapableBeanFactory的invokelnitMethods方法中调用。

6. 调用自定义init-method方法:

提供一种配置方式,在XML配置中指定Bean的初始化方法。如果Bean在配置文件中定义了初始化方法,那么该方法会被调用。
在AbstractAutowireCapableBeanFactory的invokelnitMethods方法中调用。
7. 调用BeanPostProcessor的后置处理方法:
在Bean初始化之后,再次允许BeanPostProcessor对Bean进行处理。BeanPostProcessor的postProcessAfterinitialization方法会在此时被调用。
由AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsAfterlnitialization方法执行
8. 注册Destruction回调:
如果Bean实现了DisposableBean接口或在Bean定义中指定了自定义的销毁方法,Spring容器会为这些
Bean注册一个销毁回调,确保在容器关闭时能够正确地清理资源。
在AbstractAutowireCapableBeanFactory类中的registerDisposableBeanlfNecessary方法中实现
9.Bean准备就绪:
此时,Bean已完全初始化,可以开始处理应用程序的请求了。
10. 调用DisposableBean的destroy方法:
当容器关闭时,如果Bean实现了DisposableBean接口,destroy方法会被调用。
在DisposableBeanAdapter的destroy方法中实现
11. 调用自定义的destory-method
如果Bean在配置文件中定义了销毁方法,那么该方法会被调用。
在DisposableBeanAdapter的destroy方法中实现


可以看到,整个Bean的创建的过程都依赖于AbstractAutowireCapableBeanFactory这个类,而销毁主要依赖DisposableBeanAdapter这个类。

AbstractAutowireCapableBeanFactory 的入口处,doCreateBean的核心代码如下,其中包含了实例化、设置属性值、初始化Bean以及注册销毁回调的几个核心方法。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {//实列化beanBeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = this.createBeanInstance(beanName, mbd, args);}//。。。。。。。Object exposedObject = bean;try {//设置属性值this.populateBean(beanName, mbd, instanceWrapper);//初始化beanexposedObject = this.initializeBean(beanName, exposedObject, mbd);} catch (Throwable var18) {Throwable ex = var18;if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException)ex).getBeanName())) {throw (BeanCreationException)ex;}throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);}//。。。。。try {//注册bean的销毁回调this.registerDisposableBeanIfNecessary(beanName, bean, mbd);return exposedObject;} catch (BeanDefinitionValidationException var16) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);}}

2、使用Aop可以实现哪些功能?

2.1、通过ioc实现策略模式

很多时候,我们需要对不同的场景进行不同的业务逻辑处理,举个例子,譬如不同的场景需要不同支付方式,普通
的逻辑是使用if-else,如下所示:

public void use(String code) {
if(code .equals("weixin")) {
doWeiXinPay () ;
} else if (code .equals("alipay")) {
doAlipay();
} else {
doDothing();
}

如果code越来越多,这种if-else显然非常不合适,就需要我们借助Spring来完成策略模式

package com.hellobike.moon.api.pay;import org.springframework.beans.factory.InitializingBean;
import java.util.HashMap;
import java.util.Map;/*** @author 马震* @date 2024/7/11 16:40*/
public interface PayFacade extends InitializingBean {void pay();String getCode();@Overridedefault void afterPropertiesSet() throws Exception{PayFactory.register(getCode(),this);};class WeiXinPay implements PayFacade{@Overridepublic void pay() {// by WeiXin}@Overridepublic String getCode() {return "winxin";}}class AliPay implements PayFacade{@Overridepublic void pay() {// by AliPay}@Overridepublic String getCode() {return "alipay";}}class PayFactory {private static final Map<String,PayFacade> payFacadeMap = new HashMap<>();public static void register(String scene,PayFacade payFacade){payFacadeMap.put(scene,payFacade);}public static PayFacade get(String scene){return payFacadeMap.get(scene);}}}

这样子,调用方只需要调用PayFactory#get即可,不需要感知内部的实现细节和逻辑。
需要说明的是,这里使用了InitializingBean只是实现方式之一,还有其他的实现方式,如通过Autowired注解,
BeanPostProcess等,这里不做过多赘述。

2.2、通过Aop实现拦截

很多时候,我们一般是通过注解和AOP相结合。大概的实现思路就是先定义一个注解,然后通过AOP去发现使用过该注解的类,对该类的方法进行代理处理,增加额外的逻辑,譬如参数校验,缓存,日志打印等等,如下代码所示:

@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamsCheck {boolean ignore() default false;
}
@Aspect
@Component
@Slf4j
public class ValidateAspect {/*** 定义切点* @param paramsCheck*/@Pointcut("@annotation(ParamsCheck)")public void validate(ParamsCheck paramsCheck) {}/*** 环绕通知* @param pjp* @param paramsCheck* @return*/@Around("validate(paramsCheck)")public Object ParamsCheckAround(ProceedingJoinPoint pjp,ParamsCheck paramsCheck) throws Throwable {MethodSignature methodSignature = (MethodSignature) pjp.getSignature();Method method = methodSignature.getMethod();ParamsCheck annotation = method.getAnnotation(paramsCheck.getClass());if(annotation != null && annotation.ignore()){return pjp.proceed();}Object[] args = pjp.getArgs();for (Object arg : args) {if(arg == null){break;}//参数校验,失败抛出异常}return null;}
}

根据这个思路可以做一些日志拦截,缓存逻辑等等。

3、Spring的Aop在什么场景会失效

1、私有方法调用
2、静态方法调用
3、final方法调用
4、类内部自调用
5、内部类方法调用

4、Spring事物的传播机制有哪些

Spring的事务规定了7种事务的传播级别,默认的传播机制是REQUIRED


•REQUIRED,如果不存在事务则开启一个事务,如果存在事务则加入之前的事务,总是只有一个事务在执行
•REQUIRES_NEW,每次执行新开一个事务,如果当前存在事务,则把当前事务挂起
•SUPPORTS,有事务则加入事务,没有事务则普通执行
• NOT_SUPPORTED,有事务则暂停该事务,没有则普通执行
• MANDATORY,强制有事务,没有事务则报异常
•NEVER,有事务则报异常
• NESTED,如果之前有事务,则创建嵌套事务,嵌套事务回滚不影响父事务,反之父事务影响嵌套事务

 rollbackFor
rollbackFor是Spring事务中的一个属性,用于指定哪些异常会触发事务回滚。
在一个事务方法中,如果发生了rollbackFor属性指定的异常或其子类异常,则事务会回滚。如果不指定
rollbackFor,则默认情况下只有RuntimeException和Error会触发事务回滚。

5、SpringMvc的执行流程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/45522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UDP协议介绍和作用

什么是UDP? UDP是User Datagram Protocol的简称&#xff0c;中文名是用户数据报协议&#xff0c;是OSI参考模型中的传输层协议&#xff0c;它是一种无连接的传输层协议&#xff0c;提供面向事务的简单不可靠信息传送服务。 UDP的正式规范是IETF RFC768。UDP在IP报文的协议号是…

手撸俄罗斯方块(四)——渲染与交互

手撸俄罗斯方块&#xff08;四&#xff09;——渲染与交互 如何渲染游戏界面 我们知道&#xff0c;当我们看到页面先呈现图像时&#xff0c;实际上看到的是一张图片&#xff0c;多张图片按照一定的刷新频率进行切换&#xff0c;则变成了动态的视频。当刷新频率超过24Hz时&…

DWG文件发布至IIS后无法下载和预览解决办法

问题描述 DWG文件发布至IIS后无法下载和预览 原因分析&#xff1a; iis里面需要添加扩展 解决方案&#xff1a; 在服务器端IS属性的HTTP头下的MIME内容中添加扩展名“.dwg” MIME类型填入application/acad

29.PLL(锁相环)-IP核的调用

&#xff08;1&#xff09;PLL IP核的简介&#xff1a; Phase Locked Loop&#xff0c;即锁相环&#xff0c;是最常用的IP核之一&#xff0c;其性能强大&#xff0c;可以对输入到FPGA的时钟信号进行任意分频、倍频、相位调整、占空比调整&#xff0c;从而输出一个期望时钟。锁相…

JVM学习(day1)

JVM 运行时数据区 线程共享&#xff1a;方法区、堆 线程独享&#xff08;与个体“同生共死”&#xff09;&#xff1a;虚拟机栈、本地方法栈、程序计数器 程序计数器 作用&#xff1a;记录下次要执行的代码行的行号 特点&#xff1a;为一个没有OOM&#xff08;内存溢出&a…

C语言:指针详解(4)

作者本人由于大一下学期事情繁多&#xff0c;大部分时间都在备赛&#xff0c;没有时间进行博客撰写&#xff0c;如今已经到了暑假时间&#xff0c;作者将抓紧每一天的时间进行编程语言的学习&#xff0c;由于目前作者已经进行到了C的学习&#xff0c;C语言阶段的学习与初阶数据…

Tensorflow入门实战 T08-Vgg16网络进行猫狗识别

目录 1、前言 2、代码 3、运行结果 4、反思 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 1、前言 本周学习内容为&#xff0c;采用自己设置的vgg-16网络进行猫狗识别&#xff0c;并非官网提供的…

【公益案例展】亚运天穹——践行亚运理念,筑牢安全防线

‍ 安恒信息公益案例 本项目案例由安恒信息投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2024中国数据智能产业最具社会责任感企业》榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 杭州第19届亚运会是中国第三次举办亚洲最高规格的国际综合…

217.贪心算法:加油站(力扣)

代码解决 class Solution { public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int curtotol 0; // 当前累积油量int tatol 0; // 总的油量减去总的花费油量int start 0; // 起始加油站的索引// 遍历所有加油站for (int i 0; i &…

5款文案生成神器,自动一键生成原创文案

文案在我们的生活中随处可见&#xff0c;好的文案内容不仅可以为企业带来销售转化&#xff0c;而且还能提升品牌的影响力&#xff0c;因此文案的重要性可想而知&#xff0c;对于文案创作者来说&#xff0c;写作好的文案不是轻松容易的事&#xff0c;但如果把这个任务交给文案生…

Python中的null是什么?

在知乎上遇到一个问题&#xff0c;说&#xff1a;计算机中的「null」怎么读&#xff1f; null正确的发音是/n^l/&#xff0c;有点类似四声‘纳儿’&#xff0c;在计算机中null是一种类型&#xff0c;代表空字符&#xff0c;没有与任何一个值绑定并且存储空间也没有存储值。 P…

MySQL CONCAT函数的简单使用

CONCAT函数用于将mysql中查询多列的值拼成一列显示&#xff0c; 使用示例&#xff1a; SELECT CONCAT(attr_name,"&#xff1a;",attr_value) FROM pms_sku_sale_attr_value WHERE sku_id1; 上面SQL语句使用CONCAT函数将attr_name、attr_value两列的值拼成一列&am…

动态sql 单选变多选

实体类 添加数组存储值 private ArrayList tssjfjList; <!-- <if test"tssjfj ! null and tssjfj ! ">and tssjfj #{tssjfj}</if>--><if test"tssjfjList ! null and tssjfjList.size() > 0">AND tssjfj IN<fo…

JeecgBoot 前端 vue3 项目,配置项目多页面入口

前端 vue3配置项目多页面入口 1.项目根目录新建home.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><…

Rust Hello

首先还是安装&#xff1a; 一定要换源&#xff0c;否则真的太慢了。 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh 就是~/.cargo/config [source.crates-io] # 替换成你偏好的镜像源 replace-with tuna# 清华大学 5mb [source.tuna] registry "htt…

数字信号处理教程(4)—— 离散傅里叶变换DFT

今天继续数字信号处理的学习&#xff0c;本次我们将来聊聊离散傅里叶变换DFT(Discrete Fourier Transform)。DFT是数字信号处理领域中应 用最为广泛的离散变换。DFT将一个序列x(n)映射到频率域。DFT 的许多性质都与对模拟信号进行傅里叶变换的性质相同。里面包含着大量的算法值…

论文研读:ViT-V-Net—用于无监督3D医学图像配准的Vision Transformer

目录 摘要 介绍 方法 VIT-V-Net体系结构 损失函数 图像相似性度量 变形场正则化 结果与讨论 摘要 在过去的十年里&#xff0c;卷积神经网络(ConvNets)在各种医学成像应用中占据了主导地位并取得了最先进的性能。然而&#xff0c;由于缺乏对图像中远程空间关系的理解&a…

Gitlab CI/CD介绍

基本概念 GitLab CI/CD&#xff08;持续集成/持续部署&#xff09;流水线是GitLab平台提供的一项强大功能&#xff0c;旨在通过自动化构建、测试和部署过程&#xff0c;提高开发团队的效率和软件发布的质量。 CI&#xff08;Continuous Integration&#xff09;&#xff1a;持续…

QT5.12.9 通过MinGW64 / MinGW32 cmake编译Opencv4.5.1

一、安装前准备: 1.安装QT,QT5.12.9官方下载链接:https://download.qt.io/archive/qt/5.12/5.12.9/ QT安装教程:https://blog.csdn.net/Mark_md/article/details/108614209 如果电脑是64位就编译器选择MinGW64,32位就选择MinGW32,我的是MinGW64。 2.opencv源码下载:h…

linux登入提示信息

目录 1.Linux 登录提示信息在操作系统中扮演着重要的角色 安全性提醒 欢迎信息 系统状态通知 政策和使用条款 技术支持信息 更新和变更通知 2.配置文件介绍 3.编辑配置文件 4.效果展示 修改前 修改后 “如果您在解决类似问题时也遇到了困难&#xff0c;希望我的经…