Spring面试

文章目录

  • Spring面试
    • Spring框架
      • 用了什么设计模式?
      • Spring Bean的作用域
      • Spring如何解决循环依赖
        • 什么样的循环依赖无法处理
        • 构造方法注入 VS setter注入
      • Spring框架中有哪些不同类型的事件?
      • AOP (Aspect Oriented Program) 切面编程
      • IOC容器
      • BeanFactory 与 ApplicationContext 有什么区别?
      • Spring Bean的生命周期
    • SpringMVC
      • 原理
        • 启动流程
        • 执行流程
        • Spring常用注解
        • SpringMVC设置*重定向*和*转发*
        • SpringMVC的拦截器
    • SpringBoot
    • SpringCloud
        • SpringMVC设置*重定向*和*转发*
        • SpringMVC的拦截器
    • SpringBoot
    • SpringCloud

Spring面试

Spring框架

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

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

用了什么设计模式?

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

Spring Bean的作用域

  • singleton
    • 默认作用域范围,确保不管接收到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护
  • prototype
    • 原型范围与单例范围相反,为每一个bean请求提供一个实例
  • request
    • 在请求bean范围内会为每一个来自客户端的网络请求创建一个实例,在session过期后,bean会随之失效
  • session
    • 与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效
    • request区别:request生命周期从HTTP请求发起开始,到请求处理结束结束。而session生命周期通常与用户的会话生命周期相同,从用户打开浏览器访问网站开始,到用户关闭浏览器结束

Spring如何解决循环依赖

  • 首先从一级缓存 singletonObjects中获取
  • 如果获取不到,并且对象正在创建中,就再从二级缓存 earlySingletonObjects中获取
  • 如果获取不到,且允许singletonFactories通过getObject()获取,就从三级缓存 singleFactory.getObject() 获取
  • 如果从三级缓存中获取到就从singletonFactories中移除,并放入earlySingletonObjects中。也就是从三级缓存移动到二级缓存
    • Spring解决循环依赖的诀窍就在于三级缓存 singletonFactories,它是个接口,该接口在doCreateBean方法中调用了实例化步骤,即在createBeanInstance之后调用,也就是说单例对象此时已经被创建出来(调用了构造器)。虽然还不完美,还没有进行后续步骤,但是已经能被认出来了,所以Spring将这个对象提前曝光出来让大家使用
什么样的循环依赖无法处理
  • 因为加入singletonFactories 三级缓存的前提是执行了构造器来创建半成品对象,所以构造器的循环依赖无法解决。因此,Spring不能解决A的构造方法中依赖了B的实例对象,同时B的构造方法中依赖了A
    的实例对象
    这类问题
  • Spring不支持原型(prototype)Bean属性注入循环依赖,不同于构造器注入循环依赖会在创建Spring容器Context时报错,它会在用户执行代码如context.getBean()
    时抛出异常,因为对于原型Bean,Spring容器只有在需要时才会实例化、初始化它。因为Spring容器不缓存prototype类型的Bean,使得无法提前暴露出一个创建中的Bean。Spring
    容器在获取prototype类型的Bean时,如果因为环的存在,检测到当前线程已经正在处理该Bean时,就会抛出异常
    public abstract class AbstractBeanFactoy {private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>();protected boolean isPrototypeCurrentlyInCreation(String beanName) {Object curVal = this.prototypesCurrentlyInCreation.get();return (curVal != null && (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>)curVal).contains(beanName))));} 
    }
    
构造方法注入 VS setter注入
  • setter注入不会重写构造方法的值。如果对同一个变量同时使用了构造方法注入setter注入,那么构造方法将不能覆盖由setter注入的值。很明显,因为构造方法仅在对象被创建时调用
  • setter注入有可能还不能保证某种依赖是否已经被注入,也就是说这时对象的依赖关系有可能是不完整的。而在另一种情况下,构造器注入不允许生成依赖关系不完整的对象

Spring框架中有哪些不同类型的事件?

  • 上下文更新事件 (ContextRefreshedEvent)

    • 会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext接口中的refresh()方法时被触发
  • 上下文开始事件 (ContextStartedEvent)

    • 当容器调用ConfigurableApplicationContext的start()方法开始/重新开始容器时触发该事件
  • 上下文停止事件 (ContextStoppedEvent)

    • 当容器调用ConfigurableApplicationContext的stop()方法停止容器时触发该事件
  • 上下文关闭事件 (ContextClosedEvent)

    • ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁
  • 请求处理事件 (RequestHandledEvent)

    • 在Web应用中,当一个http请求(request)结束触发该事件。如果一个Bean实现了ApplicationListener接口,当一个ApplicationEvent被发布以后,bean会自动被通知
  • 自定义事件

    public class CustomApplicationEvent extends ApplicationEvent {public CustomApplicationEvent(Object source, final String msg) {super(source);System.out.println("Created a custom event.");}
    }
    // 为了监听这个事件,还需要创建一个监听器
    public class CustomEventListener implements ApplicationListener<CustomApplicationEvent> {@Overridepublic void onApplicationEvent(CustomApplicationEvent applicationEvent) {// handle event} 
    }
    // 之后通过 applicationContext 接口的publishEvent() 方法来发布自定义事件
    CustomApplicationEvent customEvent = new CustomApplicationEvent(applicationContext, "Test Message");
    applicationContext.pulishEvent(customEvent);
    

AOP (Aspect Oriented Program) 切面编程

AOP编程思想就是把这些横向性的问题和业务逻辑进行分离,从而起到解耦的目的。

  • 使用@Aspect 定义切面类
  • 使用@PointCut 定义切点

AOP通过两种方式实现 (没有默认实现的说法)

  • java动态代理 (被代理的类必须是接口)
    • 生成的代理类的toString前缀是$Proxy
    • 生成字节码文件的字节数组
  • cglib动态代理
    • 生成的代理类的toString前缀是CGLIB$

java动态代理为什么必须是接口?因为代理类必须继承Proxy类,所以不能继承用户类,而只能是实现用户的接口

// AOP使用的代理实现,根据判断条件而来,没有默认使用其中一种的说法
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {@Overridepublic AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (config.isOptimized() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation")}if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}return new ObjenesisCglibAopProxy(config);} else {return new JdkDynamicAopProxy(config);}}
}
// 创建上下文,这里面通过后置处理器,已经生成了代理对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicatonContext(...);// 获取对象
UserService service = context.getBean(UserSerivce.class);service.doSomething();
// 获取到的service不是原生对象,是代理对象

IOC容器

  • 由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。(通过工厂模式和反射机制实现)
    。其思想是反转资源获取的方向。传统的资源查找方式要求组件向容器发起请求查找资源。作为回应,容器适时的返回资源,而应用了IOC
    之后,则是容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源,这种行为也被称为查找的被动形式

IOC容器把对象注入进去的时候,已经不是原生对象,而是代理对象了。

IOC获取到实例对象的方式

  • XML注入
  • 注解注入

BeanFactory 与 ApplicationContext 有什么区别?

  • BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当作Spring的容器。其中ApplicationContext是BeanFactory的子接口。

  • BeanFactory

    • 是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文件,管理bean的加载,实例化,控制bean的生命周期,维护bean之间的依赖关系。
  • ApplicationContext

    • 作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能。
    • 以下是三种常见的实现方式
      • ClassPathXmlAppliationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义
      • FileSystemXmlApplicationContext:由文件系统中的XML配置文件读取上下文
      • XmlWebApplicationContext:由Web应用的XML文件读取上下文
      • AnnotationConfigApplicationContext:基于Java配置启动容器

Spring Bean的生命周期

  • 实例化 Instantiation

  • 属性赋值 Populate

  • 初始化 Initialization

  • 销毁 Destruction

  • Spring提供了以下四种方式来管理Bean的生命周期事件

    • InitializingBeanDisposableBean 回调接口
    • 针对特殊行为的其它 Aware 接口
    • Bean配置文件中的Custom init() 方法和 destroy() 方法
      <beans><bean id="demoBean" class="org.newcih" init-method="customInit" destroy-method="customDestroy"/>
      </beans>
      
    • @PostConstruct@PreDestroy 注解方式

SpringMVC

MVC是软件架构模式,是一种分离业务逻辑与显示页面的设计方法,他把软件系统分为三个基本部分:模型(Model)视图(View)控制器(Controller)

  • 控制器
    对请求进行处理,负责选择视图
  • 视图
    用户与程序交互的界面
  • 模型
    用于业务处理

原理

启动流程
  • 如果在web.xml中配置了ContextLoaderListener,那么Tomcat在启动的时候会先加载父容器,并将其放到ServletContext中
  • 然后加载DispatcherServlet,因为DispatcherServlet实质是一个Servlet,所以会先执行它的init方法。这个init方法在HttpServletBean这个类中实现,其主要工作是做一些初始化工作,将我们在web.xml中配置的参数书设置到Servlet中,然后再触发FrameWorkServlet的initServletBean方法
  • FrameworkServlet主要作用是初始化Spring子上下文,设置其父上下文,并将其放入ServletContext中
  • FrameworkServlet在调用initServletBean()的过程中,同时会触发DispatcherServlet的onRefresh()方法,这个方法会初始化SpringMVC的各个功能组件。比如异常处理器、视图处理器、请求映射处理
执行流程
  • 发起请求到前端控制器 DispatcherServlet,该控制器就会过滤出你哪些请求可以访问该servlet
  • 前端控制器会找到处理器映射器 HandlerMapping,通过处理器映射器完成urlcontroller的映射
  • 通过映射器找到对应的处理器 Handler ,并将处理器返回给前端控制器。(返回的处理器前有拦截器)
  • 前端控制器拿到处理器之后,找到处理器适配器 HandlerAdapter,通过适配器来访问和执行处理器。(不能直接访问处理器,因为Spring的设计,不知道调用哪个方法,不知道处理器类如何创建出来的,如注解等等)
  • 执行处理器
  • 处理器返回ModelAndView对象给处理器适配器 HandlerAdapter
  • 通过处理器适配器 HandlerAdapterModelAndView对象返回给前端控制器(DispatcherServlet)
  • 前端控制器请求视图解析器 ViewResolver进行解析,将ModelAndView的数据进行视图渲染。
  • 最后返回结果。
Spring常用注解
  • @Controller/@RestController
    • 标注一个控制器类
  • @RequestMapping
    • 用来处理请求地址映射的注解
  • @Resource
    • 非Spring注解,做Bean的注入,默认按照名称注入,也可指定类型
  • @Autowired
    • 自动注入,按照类型装配依赖对象。如果想用按照名称,搭配@Qualifier
  • @Required
    • 应用于设值方法,它表明受影响的bean属性在配置时必须放在XML配置文件中,否则容器就会抛出一个 BeanInitializationExeption 异常
  • @ModelAttribute
    • 该Controller所有方法调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中
  • @SessionAttributes
    • 把值放到session作用域中
  • @PathVariable
    • 用于将请求URL中的模板变量映射到功能处理方法的参数上
  • @RequestParam
    • 控制层获取参数
  • @RequsetBody, @ResponseBody
    • 用于将Controller方法获取或返回的对象,通过适当的HttpMessageConverter转换为指定格式
  • @Componet
    • 通用的注解,标注组件
  • @Repository
    • 注解Dao层
  • @Service
    • 标注业务层组件类
SpringMVC设置重定向转发
  • 转发:在返回值前面加forward:
  • 重定向:在返回值前面加redirect:
SpringMVC的拦截器

SpringBoot

SpringCloud

通过适当的HttpMessageConverter转换为指定格式

  • @Componet
    • 通用的注解,标注组件
  • @Repository
    • 注解Dao层
  • @Service
    • 标注业务层组件类
SpringMVC设置重定向转发
  • 转发:在返回值前面加forward:
  • 重定向:在返回值前面加redirect:
SpringMVC的拦截器

SpringBoot

SpringCloud

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

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

相关文章

修改UnityEngine dll

修改UnityEngine dll 由于有些版本的dll与热重载并不兼容&#xff0c;需要小幅修改代码。 使用dnspy工具 我们使用 dnspy 来修改 dll文件。而dnspy只能在Win下运行&#xff0c;故哪怕是mac版本dll&#xff0c; 你也得先将相应dll复制到Win下后再修改。下载 dnspy&#xff0c…

FastAdmin青动CRM-E售后

应用介绍 一款基于FastAdminThinkPHP和uniapp开发的CRM售后管理系统&#xff0c;旨在助力企业销售售后全流程精细化、数字化管理&#xff0c;主要功能&#xff1a;客户、合同、工单、任务、报价、产品、库存、出纳、收费&#xff0c;适用于&#xff1a;服装鞋帽、化妆品、机械机…

服务器使用过程中遇到常见故障及解决方案(包括蓝屏死机、无法删除的文件如何清理、网络卡、服务器连接不上等)

互联网时代&#xff0c;服务器的安全性和稳定性尤为重要&#xff0c;支撑着整个互联网行业的信息和数据安全。最近经常有客户咨询服务器的日常故障排除方法。由于服务器复杂的硬件结构和繁琐的运行原理&#xff0c;经常会出现这样那样的问题&#xff0c;有时即使是最小的问题也…

item_get_video-获取视频详情(bili.item_get_video)

B站&#xff08;Bilibili&#xff09;的item_get_video API用于获取视频的详细信息。通过调用该API&#xff0c;您将能够获得视频的基本信息、元数据、播放链接等。这使得开发者可以轻松地将B站视频集成到自己的应用程序或网站中&#xff0c;为用户提供更丰富的内容和更好的体验…

机器学习本科课程 实验5 贝叶斯分类

实验1.使用sklearn的GaussianNB、BernoulliNB、MultinomialNB完成肿瘤预测任务 实验内容&#xff1a; 使用GaussianNB、BernoulliNB、MultinomialNB完成肿瘤预测计算各自十折交叉验证的精度、查准率、查全率、F1值根据精度、查准率、查全率、F1值的实际意义以及四个值的对比阐…

ObjectMapper之处理JSON序列化和反序列化

目录 基本示例Java 对象转 JSON 字符串&#xff08;序列化&#xff09;JSON 字符串转 Java 对象&#xff08;反序列化&#xff09; 高级特性忽略未知属性使用注解自定义序列化 当然可以。让我们通过更详细的例子来探索 ObjectMapper 的使用&#xff0c;包括基本的序列化和反序…

2-12 SDATR的训练与测试

2.12 SDATR的训练与测试 使用环境:3卡服务器SDATR 服务器代码地址:/home/lihuanyu/code/036SDATR 本地代码地址:F:\BaiduNetdiskDownload\code\036SDATR 2.12.1 训练文件修改 输入数据修改 载入词汇修改 短点保存修改 权重保存修改 其他位置修改:

springboot果蔬配送商城

技术架构&#xff1a; java mysql bootstrap jquery mybatis springboot 有需要该项目的小伙伴可以私信我你的Q。 功能介绍&#xff1a; 系统基于Java技术进行开发&#xff0c;后台数据库使用MySQL&#xff0c;在Windows环境下使用idea开发工具进行开发&#xff0c;主…

【计算机网络基础篇】学习笔记系列之二《游览器输入URL后发生了什么?》

文章目录 1&#xff0c;问题提出2&#xff0c;输入URL过程用到的协议3&#xff0c;输入URL过程分析3.1&#xff0c;孤单小弟 - HTTP3.2&#xff0c;真实地址查询 - DNS3.2&#xff0c;指南好帮手 - 协议栈3.3&#xff0c;可靠传输 - TCP3.4&#xff0c;远程定位- IP3.5&#xf…

Ardupilot Chibios硬件启动初始化过程整理

ardupilot 的启动根据不同HAL 的启动过程不一样 &#xff0c; chibios 的硬件入口是 硬件启动 -> modules/Chibios/common/startup/ARMCMx/compilers/GCC/VECTOR.S ResetHandler: modules/Chibios/common/startup/ARMCMx/compilers/GCC/ crt0_v7m.S crt0_entry--AP_HAL_Chi…

陶哲轩如何用 GPT-4 辅助数学研究

关于陶哲轩&#xff08;Terence Tao&#xff09;用 GPT-4 进行数学研究的话题始于陶本人在 微软 Unlocked 上发表的 Embracing Change and Resetting Expectations 一文。文中提到&#xff1a; …… I could feed GPT-4 the first few PDF pages of a recent math preprint and…

[学习笔记]刘知远团队大模型技术与交叉应用L6-基于大模型文本理解和生成介绍

介绍 NLP的下游运用可以分为&#xff1a;NLU(理解)和NLG(生成) 信息检索&#xff1a;NLU 文本生成&#xff1a;NLG 机器问答&#xff1a;NLUNLG 大模型在信息检索 大模型在机器问答 大模型在文本生成 信息检索-Information Retrieval (IR) 背景 谷歌搜索引擎目前同时集成了…

【Ubuntu】安装filebeat

在Ubuntu系统上安装filebeat 1. 添加ElasticSearch的GPG密钥 wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -2. 添加ElasticSearch的APT存储库 echo "deb https://artifacts.elastic.co/packages/oss-8.x/apt stable main"…

Docker 可视化工具

1、Portainer 概念介绍 Portainer是一款轻量级的应用&#xff0c;它提供了图形化界面&#xff0c;用于方便地管理Docker环境&#xff0c;包括单机环境和集群环境。 Portainer分为开源社区版&#xff08;CE版&#xff09;和商用版&#xff08;BE版/EE版&#xff09;。 Porta…

嵌入式学习第十六天!(Linux文件查看、查找命令、标准IO)

Linux软件编程 1. Linux&#xff1a; 操作系统的内核&#xff1a; 1. 管理CPU 2. 管理内存 3. 管理硬件设备 4. 管理文件系统 5. 任务调度 2. Shell&#xff1a; 1. 保护Linux内核&#xff08;用户和Linux内核不直接操作&#xff0c;通过操作Shell&#xff0c;Shell和内核交互…

idea常用设置

1、内存优化 根据自己电脑本身的内存&#xff0c;对idea安装包里bin目录下的idea64.exe.vmoptions文件进行修改 -server -Xms256m -Xmx2048m -XX:MaxPermSize1024m -XX:ReservedCodeCacheSize256m -ea -Dsun.io.useCanonCachesfalse -Djava.Net.preferIPv4Stacktrue -Djsse.e…

2024 极术通讯-安谋科技2023精彩征程回顾

导读&#xff1a;极术社区推出极术通讯&#xff0c;引入行业媒体和技术社区、咨询机构优质内容&#xff0c;定期分享产业技术趋势与市场应用热点。 芯方向 使用 Arm SPE 进行芯片数据采集和性能分析 Arm Statistical Profiling Extension (SPE, 统计分析扩展) 是一种架构级功…

CSS:水平垂直居中

公共的 CSS 样式&#xff1a; .parent {width: 300px;height: 300px;background-color:#d0e4fe; }.child {width: 100px;height: 100px;background-color:orange; }HTML: <div class"parent"><div class"child"></div> </div>最…

docker-compose部署laravel项目实战(主机nginx连接项目容器)(详细配置过程)

我用的是主机上的nginx,没有用docker安装nginx&#xff0c; 所以需要先在主机上安装nginx # 更新系统yum sudo yum update# 安装安装包sudo yum install epel-release sudo yum install wget# 安装Nginx sudo yum install nginx #启动 sudo systemctl start nginx #开机自启动…

Centos7配置登录失败处理导致root被锁定处理办法

1、应用场景 root用户被系统锁定&#xff0c;无法登录系统。 2、问题现象 root锁定无法登录系统 3、原因 设置登录失败处理并对root用户生效&#xff0c;一直尝试错误的root密码或暴力破解root密码&#xff0c;导致无法自动解锁Linux的root账户 4、解决方案 1.将虚拟机开…