2024年java面试(四)--spring篇

文章目录

  • 1.BeanFactory 和 FactoryBean 的区别
  • 2.BeanFactory和ApplicationContext有什么区别?
  • 3.@RequestBody、@RequestParam、@ResponseBody
  • 4.cookie和session的区别
  • 5.Servlet的生命周期
  • 6.Jsp和Servlet的区别
  • 7.SpringMvc执行流程
  • 8.@RequestMapping是怎么使用
  • 9.如果一个接口有多个实现类,在springboot中如何调用不同实现类中的方法
  • 10.拦截器的配置
  • 11.分页功能实现
  • 12.如何定义一个全局异常处理类?
  • 13.说出Spring或者SpringMVC中常用的5个注解
  • 14.简述SpringMVC中如何返回JSON数据
  • 15.什么是循环依赖?
  • 16.为什么构造器注入属性无法解决循环依赖问题?
  • 17.一级缓存能不能解决循环依赖问题? 不能
  • 18.二级缓存能不能解决循环依赖问题?


1.BeanFactory 和 FactoryBean 的区别

BeanFactory: 是 IOC 容器,并且提供方法支持外部程序对这些 bean 的访问,在程序启动时 根据传入的参数产生各种类型的 bean,并添加到 IOC容器(实现 BeanFactory接口的类) 的 singletonObject 属性中。

FactoryBean: 首先是个 bean,也存放在 BeanFactory 中。它具有工厂方法的功能,在程序运行中 产生指定(一种)类型的 bean,并添加到了 IOC容器中的 factoryBeanObjectCache 属性中。

首先 FactoryBean 是一个 bean,但它又不仅仅是个 bean。它是一个可以 创建 或 修饰 其他对象的”工厂 bean“,这跟设计模式中的工厂模式或者装饰器模式很相似,它可以创建除自身以外的其他对象。


2.BeanFactory和ApplicationContext有什么区别?

ApplicationContext是BeanFactory的子接口

ApplicationContext提供了更完整的功能:
①继承MessageSource,因此支持国际化。
②统一的资源文件访问方式。
③提供在监听器中注册bean的事件。
④同时加载多个配置文件。
⑤载入多个(有继承关系)上下文,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

  • BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。
  • ApplicationContext,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean
    ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。
  • 相对于基本的BeanFactory,ApplicationContext
    唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
    BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。

3.@RequestBody、@RequestParam、@ResponseBody

RequestBody注解的主要作用就是用于接收前端的参数,当我们使用post请求的时候,我们会将参数放在request body中,此时我们就需要在Controller的方法的参数前面加上@RequestBody用来接受到前端传过来的request body中的值 (将请求体中的JSON数据自动解析成Java对象)

RequestParam接收的参数主要是来自request Header中,即请求头中。通常用于get请求中,我们都知道get请求的参数都是写在url中的,例如:http://localhost:8080/my/api/testMethod?name=雷神&age=3 该url我们可以看到有name和age两种属性,那么当我们将此请求发送到后台服务以后,现在解释一下@RequestParam的括号中的三个参数的意思,value值得就是请求的url中必须要有的参数名,相当于key值;required表示的是是否为必须,也就是说参数在url中是否为必须,默认的是true;defaultValue指的则是参数的默认值; (将请求参数的值映射到控制器方法的参数上,从而方便地获取和使用这些参数)

Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用;通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。ResponseBody的作用是将后端以return返回的javabean类型数据转为json类型数据。将java对象转为json格式的数据


4.cookie和session的区别

cookie不是很安全,它的数据是存放在客户的浏览器上,单个cookie保存的数据不能超过4K。

session比较安全,它会在一定时间内保存在服务器上,但是当访问增多,会比较占用服务器的性能,所以考虑到减轻服务器性能方面,应当使用cookie。


5.Servlet的生命周期

加载类—>实例化(为对象分配空间)—>初始化(为对象的属性赋值)—>请求响应(服务阶段)—>销毁


6.Jsp和Servlet的区别

Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。

而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。

JSP侧重于视图,Servlet主要用于控制逻辑

Servlet更多的是类似于一个Controller,用来做控制。


7.SpringMvc执行流程

在这里插入图片描述

①客户端(浏览器)发送请求,直接请求到 DispatcherServlet(前端控制器) 。
②DispatcherServlet 根据请求信息调⽤ HandlerMapping ,解析请求对应的 Handler 。
③解析到对应的 Handler (也就是 Controller 控制器)后,开始由HandlerAdapter 适配器处理。
④HandlerAdapter 会根据 Handler 来调⽤真正的处理器来处理请求,并处理相应的业务逻辑。
⑤处理器处理完业务后,会返回⼀个 ModelAndView 对象, Model 是返回的数据对象
⑥ViewResolver 会根据逻辑 View 查找实际的 View 。
⑦DispaterServlet 把返回的 Model 传给 View (视图渲染)。
⑧把 View 返回给请求者(浏览器)


8.@RequestMapping是怎么使用

在Controller类的方法下使用这个注解,作用就是映射URL路径,将http的请求地址映射到控制器。返回值交给视图解析器解析,如果配合@ResponseBody则返回JSON或者XML数据


9.如果一个接口有多个实现类,在springboot中如何调用不同实现类中的方法

public interface Animal {//动物的叫声public void call();//动物吃的东西public void eat();
}
​
实现类1
@Service("dogImpl")
public class Dog implements Animal {@Overridepublic void call() {System.out.println("汪汪汪......");}@Overridepublic void eat() {System.out.println("骨头");}
}
​
实现类2
@Service("catImpl")
public class Cat implements Animal {@Overridepublic void call() {System.out.println("喵喵喵......");}@Overridepublic void eat() {System.out.println("鱼");}
}

方法1 指明实现类的优先级

在写实现类的时候事先指明实现类的优先级,注入的时候就会使用优先级高的实现类。在调用的类中注入接口,默认使用的是Primary 标注的实现类的方法

@Service("dog")
@Primary
public class Dog implements Animal {.......
}

方法2 通过@Autowride和@Qualifier两个注解配合使用

在调用处使用这两个注解

@Autowired
@Qualifier("dog")
private Animal animal;    //正常启动

注:注解@Qualifier内的值是实现类的默认名

方法3 使用@Resource注解,默认类名区分

在调用处使用此注解

@Resource(name = "dog")
private Animal animal;     //正常启动

注:注解@Qualifier内的值是实现类中@Service指定的名字


10.拦截器的配置

第一步,实现HandlerInterceptor接口的拦截器

public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 在请求处理之前进行拦截处理return true; // 返回true表示继续执行请求处理,返回false表示中断请求处理}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// 在请求处理之后进行拦截处理}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception {// 在请求处理完成之后进行拦截处理}
}
@Configuration
public class SpringMvcSupport extends webMvcConfigurationSupport {@Autowiredprivate MyInterceptor myInterceptor;@verrideprotected void addInterceptors( InterceptorRegistry registry){          registry.addInterceptor(projectInterceptor).addPathPatterns("/路径");}
}

第二步,使用注解的拦截器

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// 判断请求方法是否有MyAnnotation注解if (handler instanceof HandlerMethod) {HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();if (method.isAnnotationPresent(MyAnnotation.class)) {// 在请求处理之前进行拦截处理return true; // 返回true表示继续执行请求处理,返回false表示中断请求处理}
}return true;
}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) throws Exception {// 在请求处理之后进行拦截处理}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) throws Exception {// 在请求处理完成之后进行拦截处理}
}@Controller
public class MyController {@RequestMapping("/test")@MyAnnotationpublic String test() {// 处理请求return "test";}
}

11.分页功能实现

@Test
void testGetPage(){IPage page = new Page( "current": 1"size": 5);bookDao.selectPage(page, "queryWrapper": null);page.getCurrent();//获取当前页page.getSize();//获取每页数量page.getTotal();//获取总共数据条数page.getPages();//获取一共多少页page.getRecords();//获取的数据
}//配置拦截器实现分页
@Configuration
public class MPConfig{@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(){MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor( ));return interceptor;}
}

12.如何定义一个全局异常处理类?

想要定义一个全局异常处理类的话,我们需要在这个类上添加@ContaollerAdvice注解,然后定义一些用于捕捉不同异常类型的方法,在这些方法上添加@ExceptionHandler(value = 异常类型.class)和@ResponseBody注解,方法参数是HttpServletRequest和异常类型,然后将异常消息进行处理。

如果我们需要自定义异常的话,就写一个自定义异常类,该类需要继承一个异常接口,类属性包括final类型的连续id、错误码、错误信息,再根据需求写构造方法;


13.说出Spring或者SpringMVC中常用的5个注解

@Component 基本注解,标识一个受Spring管理的组件

@Controller 标识为一个表现层的组件

@Service 标识为一个业务层的组件

@Repository 标识为一个持久层的组件

@Autowired 自动装配

@Qualifier(“”) 具体指定要装配的组件的id值

@RequestMapping() 完成请求映射

@PathVariable 映射请求URL中占位符到请求处理方法的形参


14.简述SpringMVC中如何返回JSON数据

Step1:在项目中加入json转换的依赖,例如jackson,fastjson,gson等

Step2:在请求处理方法中将返回值改为具体返回的数据的类型, 例如数据的集合类List等

Step3:在请求处理方法上使用@ResponseBody注解


15.什么是循环依赖?

循环依赖就是在创建 A 实例的时候里面包含着 B 属性实例,所以这个时候就需要去创建 B 实例,而创 建 B 实例过程中也包含着 A 实例。 这样 A 实例还在创建的过程当中,所以就导致 A 和 B 实例都创建不出来。

在这里插入图片描述
spring通过三级缓存来解决循环依赖:

一级缓存:缓存经过完整的生命周期的Bean

二级缓存 :缓存未经过完整的生命周期的Bean

三级缓存:缓存的是ObjectFactory,其中存储了一个生成代理类的拉姆达表达式

我们在创建 A 的过程中,先将 A 放入三级缓存 ,这时要创建B,B要创建A就直接去三级缓存中查找,并且判断需不需要进行 AOP 处理,如果需要就执行拉姆达表达式得到代理对象,不需要就取出原始对象。然后将取出的对象放入二级缓存中,因为这个时候 A 还未经 过完整的生命周期所以不能放入一级缓存。这个时候其他需要依赖 A 对象的直接从二级缓存中去获取即可。当B创建完成,A 继续执行生命周期,当A完成了属性的注入后,就可以放入一级缓存了


16.为什么构造器注入属性无法解决循环依赖问题?

由于spring中的bean的创建过程为先实例化 再初始化(在进行对象实例化的过程中不必赋值)将实例化好的对象暴露出去,供其他对象调用,然而使用构造器注入,必须要使用构造器完成对象的初始化的操作,就会陷入死循环的状态


17.一级缓存能不能解决循环依赖问题? 不能

在三个级别的缓存中存储的对象是有区别的 一级缓存为完全实例化且初始化的对象 二级缓存实例化但未初始化对象 如果只有一级缓存,如果是并发操作下,就有可能取到实例化但未初始化的对象,就会出现问题


18.二级缓存能不能解决循环依赖问题?

理论上二级缓存可以解决循环依赖问题,但是需要注意,为什么需要在三级缓存中存储匿名内部类(ObjectFactory),原因在于 需要创建代理对象 eg:现有A类,需要生成代理对象 A是否需要进行实例化(需要) 在三级缓存中存放的是生成具体对象的一个匿名内部类,该类可能是代理类也可能是普通的对象,而使用三级缓存可以保证无论是否需要是代理对象,都可以保证使用的是同一个对象,而不会出现,一会儿使用普通bean 一会儿使用代理类

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

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

相关文章

爬虫逆向实战(二十七)--某某招标投标网站招标公告

一、数据接口分析 主页地址:某网站 1、抓包 通过抓包可以发现数据接口是page 2、判断是否有加密参数 请求参数是否加密? 通过查看“载荷”模块可以发现,请求参数是一整个密文 请求头是否加密? 无响应是否加密? 通…

Mac下使用Homebrew安装MySQL5.7

Mac下使用Homebrew安装MySQL5.7 1. 安装Homebrew & Oh-My-Zsh2. 查询软件信息3. 执行安装命令4. 开机启动5. 服务状态查询6. 初始化配置7. 登录测试7.1 终端登录7.2 客户端登录 参考 1. 安装Homebrew & Oh-My-Zsh mac下如何安装homebrew MacOS安装Homebrew与Oh-My-Zsh…

使用DataX对MySQL 8.1进行数据迁移

1. 环境准备 1.1 下载DataX 这里采用直接下载的方式:https://datax-opensource.oss-cn-hangzhou.aliyuncs.com/202308/datax.tar.gz,不过这个包是真的有点大。 1.2 安装Python Python下载地址:https://www.python.org/downloads/ 安装的时…

运维Shell脚本小试牛刀(一)

运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 一: Shell中循环剖析 for 循环....... #!/bin/bash - # # # # FILE: countloop.sh # USAGE: ./countloop.sh # DESCRIPTION: # OPTIONS: ------- # …

泰迪大数据实训平台产品介绍

大数据产品包括:大数据实训管理平台、大数据开发实训平台、大数据编程实训平台等 大数据实训管理平台 泰迪大数据实训平台从课程管理、资源管理、实训管理等方面出发,主要解决现有实验室无法满足教学需求、传统教学流程和工具低效耗时和内部教学…

C++ 读写Excel LibXL库的使用附注册码(key)

LibXL是一款用于读写处理 Excel 文件的库,支持C, C++, C#,Python等语言。并且支持多个平台windows、Linux、Mac等,它提供了一系列的API,让开发人员可以方便地读取、修改和创建Excel文件。 一、关于库的key与使用 1.价值3000多的key 但是这个库并不是免费的,使用此库需要…

[Android AIDL] --- AIDL原理简析

上一篇文章已经讲述了如何在Android studio中搭建基于aidl的cs模型框架,只是用起来了,这次对aidl及cs端如何调用的原理进行简单分析 1 创建AIDL文件 AIDL 文件可以分为两类。 一类是用来定义接口方法,声明要暴露哪些接口给客户端调用&#…

Gitlab设置中文

1. 打开设置 2.选择首选项Preferences 3. 下滑选择本地化选项Localization,设置简体中文,然后保存更改save changes。刷新网页即可。

电脑识别不了固态硬盘怎么办?

在使用固态硬盘时,可能会出现电脑无法识别的情况,这时我们就无法使用固态硬盘中的数据。那么,电脑识别不了固态硬盘怎么办? 为什么电脑识别不了固态硬盘? 一般来说,电脑识别不了固态硬盘是因为以下3个原因…

博流RISC-V芯片JTAG debug配置与运行

文章目录 1、Windows下安装与配置2、Linux下安装与配置3、芯片默认 JTAG PIN 列表4、命令行运行JTAG5、Eclipse下使用JTAG 1、Windows下安装与配置 CKLink 驱动安装 Windows版驱动下载地址: https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1666331…

C语言_初识C语言指针

文章目录 前言一、指针 ... 一个内存单元多大比较合适?二、地址或者编号如何产生?三、指针变量的大小 前言 内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的。 所以为了有效的使用内存,就把内存划分成一个个…

基于java Swing 和 mysql实现的购物管理系统(源码+数据库+说明文档+运行指导视频)

一、项目简介 本项目是一套基于java Swing 和 mysql实现的购物管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、项目文档、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过…

java八股文面试[多线程]——Synchronized的底层实现原理

笔试:画出Synchronized 线程状态流转实现原理图 synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是同步,也称之为”同步锁“。 synchronized的作用是保证在同一时刻, 被修饰的代码块或方…

vue h5项目 打包加载优化

打包美化: 1)npx browserslistlatest --update-db 更新去除警告 2)打包进度条 npm add progress-bar-webpack-plugin -D npm add webpackbar -D npm install --save-dev webpack-bundle-analyzer 优化: 1.各个插件和loader所花费的时间 …

C#,数值计算——高斯权重(GaussianWeights)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public class GaussianWeights { private static double[] x { 0.1488743389816312, 0.4333953941292472, 0.6794095682990244, 0.8650633666889845, 0.9739065285171717 …

LNMP架构之搭建Discuz论坛

LNMP 一、编译安装Nginx1)前置准备2)开始编译安装3)添加到系统服务(systemd启动) 二、编译安装MySQL服务1)前置准备2)编译安装3)编辑配置文件4)更改mysql安装目录和配置文…

VR全景展示:打造三维、立体化的VR房产参观方式

我们从近期的新闻中可以了解到,房地产行业正在经历挑战和压力,因为房地产销售市场的持续低迷,导致很多公司出现了债务危机。线下销售模式效果不佳,很多房企开始转战线上销售,VR全景展示方案为房地产销售带来了全新的体…

下面是实践百度飞桨上面的pm2.5分类项目_logistic regression相关

part1:数据的引入,和前一个linear regression基本是一样 part2:数据解析——也就是数据的“规格化” 首先,打算用dataMat[]和labelMat[]数据存储feature和label,并且文件变量fr 然后,是这个for line in fr.readlines()循环&#…

华为OD机试 - MELON的难题 - 动态规划(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、动态规划五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明华为OD机试 2023B卷题库疯狂收录中,刷题点这里 一、题目描述 MELON有一堆精美的雨花石(数量为n,重量各异),准备送给S和W。MELON希望送给俩人的雨花石…

【javaweb】学习日记Day6 - Mysql 数据库 DDL DML

之前学习过的SQL语句笔记总结戳这里→【数据库原理与应用 - 第六章】T-SQL 在SQL Server的使用_Roye_ack的博客-CSDN博客 目录 一、概述 1、如何安装及配置路径Mysql? 2、SQL分类 二、DDL 数据定义 1、数据库操作 2、IDEA内置数据库使用 (1&…