spring框架-如何面试(四)

简介: spring框架-如何面试(四)

回顾:

spring框架-认识spring框架(一)


spring框架-认识IOC(二)


spring框架-认识AOP(三)


面试官关于spring最喜欢、也是概率最大的提问


谈谈你对spring的理解

spring的官方定义:

Spring 是一个轻量级的控制反转 (IOC) 和面向切面 (AOP) 的开源容器框架


spring有一些优点:


1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦


2.可以使用容器提供的众多服务,如事务管理,消息服务等


3.容器提供单例模式支持


4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控,系统日志等功能


5.容器提供了众多的辅助类,能加快应用的开发


6.spring对于主流的应用框架提供了集成支持,如hibernate,mybatis,Struts2等


7.spring属于低侵入式设计,代码的污染极低


8.独立于各种应用服务器


9.spring的DI机制(依赖注入)降低了业务对象替换的复杂性


10.Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring


的部分或全部。

可以说spring是程序员的春天。


可以从IOC和AOP的理解入手说明


spring框架-认识IOC(二)


spring框架-认识AOP(三)


谈谈你对IOC的理解

这是一个衍生问题:


什么是IOC?--> 为什么要IOC-->控制反转 是控制了谁对谁的反转?-->IOC容器完成了哪些事情-->做的这些事情与工厂模式有什么异同。


什么是IOC

IoC(Inversion of Control)控制反转,它是类与类依赖关系交给容器处理。


有个网友对IOC形容得很贴切:https://www.zhihu.com/question/48427693?sort=created

为什么要用IOC

减少了对象的创建和管理 ,使代码层次更加清晰。

Spring 的IOC容器是一个轻量级的容器 ,没有侵入性(不依赖容器的API) ,不需要实现一些特殊接口。

鼓励我们面向接口编程。

减少了代码的耦合,将耦合的部分推到了配置文件中 ,如果他们的关系发生了改变,只需要修改配置文件。


控制反转 是控制了谁对谁的反转

控制指的是:当前对象对内部成员的控制权。

反转指的是:这种控制权不由当前对象管理了,由其他(类,第三方容器)来管理

传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;


IOC容器完成了哪些事情

IOC容器其实就是一个大工厂,它用来管理我们所有的对象以及依赖关系


通过反射我们可以获取类的所有信息(成员变量、类名等等等)!

再通过配置文件(xml)或者注解来描述类与类之间的关系

我们就可以通过这些配置信息和反射技术来构建出对应的对象和依赖关系了

IOC做的这些事情与工厂模式有什么异同

相同点:把主动变被动:产品的具体实现(生产)交给工厂处理,而业务逻辑(客户代码)只需要向工厂索要产品即可,他并不关心,工厂如何生产,并且生产什么。只要符合我们之前约定的产品本质即可


不同的地方:IOC不再需要程序主动去new对象,你看不到new操作,也看不到工厂模式的代码了。用户只要关注业务代码就可以。



谈谈你对AOP的理解

这也是一个衍生问题:什么是AOP?--> 能做什么--> 一个简单的AOP打算怎么实现?


什么是AOP

面向切面(方面)编程


aop能做什么

可以把业务逻辑和系统级的服务进行隔离(系统级的服务像系统的日志,事务,权限验证等)


一个简单的AOP打算怎么实现

实现一个业务系统日志切面


1、定义注解logimage.png 对请求路径进行拦截处理--操作日志记录拦截

1.public class LogHandlerInterceptor implements HandlerInterceptor {
//    请求处理之前进行调用
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        long startTime = System.currentTimeMillis();
        request.setAttribute("startTime", startTime);
        return true;
    }
//    请求处理之后,DispatcherServlet进行视图返回渲染之前进行调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerMethod handler2=(HandlerMethod) handler;
        Log log = handler2.getMethod().getAnnotation(Log.class);//可以得到log对象数据
        System.out.println("处理log日志");
    }
//    在DispatcherServlet 渲染了对应的视图之后执行。用于进行资源清理
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        long payTime = System.currentTimeMillis()-(long) request.getAttribute("startTime");//业务处理花费时间
        System.out.println("afterCompletion 业务处理好,资源清理完成,返回前端");
    }
}

解释Spring Bean的生命周期


Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。


Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。


初始化之后调用的回调方法。

销毁之前调用的回调方法。

Spring框架提供了以下四种方式来管理bean的生命周期事件:


InitializingBean和DisposableBean回调接口

针对特殊行为的其他Aware接口

Bean配置文件中的Custom init()方法和destroy()方法

@PostConstruct和@PreDestroy注解方式

使用customInit()和 customDestroy()方法管理bean生命周期的代码样例如下:


<beans> <bean id="demoBean" class="com.somnus.task.DemoBean" init-method="customInit" destroy-method="customDestroy"></bean> </beans>


Spring Bean的作用域


Spring容器中的bean可以分为5个范围。所有范围的名称都是自说明的,但是为了避免混淆,还是让我们来解释一下:


singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。

prototype:原形范围与单例范围相反,为每一个bean请求提供一个实例。

request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

Session:与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。

global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。

全局作用域与Servlet中的session作用域效果相同。使用3,4,5作用域的,需要手动设置代理


BeanFactory和ApplicationContext有什么区别


BeanFactory 可以理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。


BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。BeanFactory还包含了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。


application context是beanFactory的子接口,拥有BeanFactory的所有功能,但applicationcontext在此基础上还提供了其他的功能。


提供了支持国际化的文本消息

统一的资源文件读取方式

已在监听器中注册的bean的事件

且beanFactory是延迟加载,需要类的时候才创建类的实例,而ApplicationContext在初始化时就加载完成了所有的单例bean

以下是三种较常见的 ApplicationContext 实现方式:


1、ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中取得


   ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);  

2、FileSystemXmlApplicationContext :由文件系统中的XML配置文件读取上下文。

ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);


3、XmlWebApplicationContext:由Web应用的XML文件读取上下文。


Spring框架中的单例Beans是线程安全的吗

Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定。但实际上,大部分的Spring bean并没有可变的状态(比如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(比如 View Model 对象),就需要自行保证线程安全。

最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”。


构造方法注入和属性注入有什么区别

在属性注入方法支持大部分的依赖注入,如果我们仅需要注入int、string和long型的变量,我们不要用设值的方法注入。对于基本类型,如果我们没有注入的话,可以为基本类型设置默认值。在构造方法注入不支持大部分的依赖注入,因为在调用构造方法中必须传入正确的构造参数,否则的话为报错。

属性注入不会重写构造方法的值。如果我们对同一个变量同时使用了构造方法注入又使用了设置方法注入的话,那么构造方法将不能覆盖由设值方法注入的值。很明显,因为构造方法尽在对象被创建时调用。

在使用属性注入时有可能还不能保证某种依赖是否已经被注入,也就是说这时对象的依赖关系有可能是不完整的。而在另一种情况下,构造器注入则不允许生成依赖关系不完整的对象。

在属性注入时如果对象A和对象B互相依赖,在创建对象A时Spring会抛出sObjectCurrentlyInCreationException异常,因为在B对象被创建之前A对象是不能被创建的,反之亦然。所以Spring用设值注入的方法解决了循环依赖的问题,因对象的设值方法是在对象被创建之前被调用的。

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


Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:


代理模式—在AOP和remoting中被用的比较多。

单例模式—在spring配置文件中定义的bean默认为单例模式。

模板方法—用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

前端控制器—Spring提供了DispatcherServlet来对请求进行分发。

视图帮助(View Helper )—Spring提供了一系列的JSP标签,高效宏来辅助将分散的代码整合在视图里。

依赖注入—贯穿于BeanFactory / ApplicationContext接口的核心理念。

工厂模式—BeanFactory用来创建对象的实例。

后续会不定期更新关于spring面试题目和答案。。再见


image.png

目录
相关文章
|
2天前
|
运维 NoSQL Java
SpringBoot接入轻量级分布式日志框架GrayLog技术分享
在当今的软件开发环境中,日志管理扮演着至关重要的角色,尤其是在微服务架构下,分布式日志的统一收集、分析和展示成为了开发者和运维人员必须面对的问题。GrayLog作为一个轻量级的分布式日志框架,以其简洁、高效和易部署的特性,逐渐受到广大开发者的青睐。本文将详细介绍如何在SpringBoot项目中接入GrayLog,以实现日志的集中管理和分析。
16 1
|
6天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
27 2
|
6天前
|
Cloud Native 安全 Java
Micronaut对决Spring Boot:谁是微服务领域的王者?揭秘两者优劣,选对框架至关重要!
【9月更文挑战第5天】近年来,微服务架构备受关注,Micronaut和Spring Boot成为热门选择。Micronaut由OCI开发,基于注解的依赖注入,内置多种特性,轻量级且启动迅速;Spring Boot则简化了Spring应用开发,拥有丰富的生态支持。选择框架需考虑项目需求、团队经验、性能要求及社区支持等因素。希望本文能帮助您选择合适的微服务框架,助力您的软件开发项目取得成功!
35 2
|
8天前
|
JavaScript 前端开发 Java
【颠覆传统】Spring框架如何用WebSocket技术重塑实时通信格局?揭秘背后的故事与技术细节!
【9月更文挑战第4天】随着Web应用对实时交互需求的增长,传统的HTTP模型已无法满足现代应用的要求,特别是在需要持续、双向通信的场景下。WebSocket协议由此诞生,提供全双工通信渠道,使服务器与客户端能实时互发消息。作为Java开发中最受欢迎的框架之一,Spring通过其WebSocket模块支持这一协议,简化了WebSocket在Spring应用中的集成。
28 0
|
11天前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
15 0
|
11天前
|
消息中间件 Kafka Java
Spring 框架与 Kafka 联姻,竟引发软件世界的革命风暴!事件驱动架构震撼登场!
【8月更文挑战第31天】《Spring 框架与 Kafka 集成:实现事件驱动架构》介绍如何利用 Spring 框架的强大功能与 Kafka 分布式流平台结合,构建灵活且可扩展的事件驱动系统。通过添加 Spring Kafka 依赖并配置 Kafka 连接信息,可以轻松实现消息的生产和消费。文中详细展示了如何设置 `KafkaTemplate`、`ProducerFactory` 和 `ConsumerFactory`,并通过示例代码说明了生产者发送消息及消费者接收消息的具体实现。这一组合为构建高效可靠的分布式应用程序提供了有力支持。
38 0
|
11天前
|
Java Spring 人工智能
AI 时代浪潮下,Spring 框架异步编程点亮高效开发之路,你还在等什么?
【8月更文挑战第31天】在快节奏的软件开发中,Spring框架通过@Async注解和异步执行器提供了强大的异步编程工具,提升应用性能与用户体验。异步编程如同魔法,使任务在后台执行而不阻塞主线程,保持界面流畅。只需添加@Async注解即可实现方法的异步执行,或通过配置异步执行器来管理线程池,提高系统吞吐量和资源利用率。尽管存在线程安全等问题,但异步编程能显著增强应用的响应性和效率。
23 0
|
11天前
|
测试技术 Java Spring
Spring 框架中的测试之道:揭秘单元测试与集成测试的双重保障,你的应用真的安全了吗?
【8月更文挑战第31天】本文以问答形式深入探讨了Spring框架中的测试策略,包括单元测试与集成测试的有效编写方法,及其对提升代码质量和可靠性的重要性。通过具体示例,展示了如何使用`@MockBean`、`@SpringBootTest`等注解来进行服务和控制器的测试,同时介绍了Spring Boot提供的测试工具,如`@DataJpaTest`,以简化数据库测试流程。合理运用这些测试策略和工具,将助力开发者构建更为稳健的软件系统。
21 0
|
11天前
|
容器 Java Spring
Spring框架遇上Docker:传统与现代的碰撞,谁将重塑应用部署的未来?
【8月更文挑战第31天】Spring框架凭借其强大的企业级特性和便捷的开发模式,在Java开发中占据重要地位。Docker作为容器化技术的代表,提供了轻量级、可移植的应用部署解决方案。两者结合,尤其在微服务架构中,能显著提升开发效率、部署速度和环境一致性。
28 0
|
11天前
|
Java Spring 自然语言处理
Spring 框架里竟藏着神秘魔法?国际化与本地化的奇妙之旅等你来揭开谜底!
【8月更文挑战第31天】在软件开发中,国际化(I18N)与本地化(L10N)对于满足不同地区用户需求至关重要。Spring框架提供了强大支持,利用资源文件和`MessageSource`实现多语言文本管理。通过配置日期格式和货币符号,进一步完善本地化功能。合理应用这些特性,可显著提升应用的多地区适应性和用户体验。
24 0