version:1.0

文章目录


【面试篇】SpringIoC、AOP、MVC面试实战-LMLPHP

Spring

Spring基础 / IoC

🙎‍♂️面试官:举例Spring的模块?

🙋‍♂答:

Spring是一套为了简化企业级开发的开源框架,主要思想是Spring IoC 和Spring AOP。

spring-core:Spring框架基本的核心组件,包含很多关键类。

spring-beans:提供对bean的创建、解析等功能的支持。

spring-aspects :该模块为 AspectJ 的集成提供支持。

spring-aop :提供对面向切面的编程的支持。

spring-webmvc : 提供对 Spring MVC 的实现。

🙎‍♂️面试官:Spring、SpringMVC、Spring Boot关系?

🙋‍♂答:

Spring MVC是Spring中的一个重要模块,可以帮助我们快速构建MVC架构的Web应用。

Spring Boot可以简化可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。
但是在需要构建MVC架构的程序时,还是需要使用Spring MVC作为MVC框架。

🙎‍♂️面试官:说说对SpringIoC的了解?

🙋‍♂答:

IoC是控制反转。我们直接使用注解,就可以将对象装配到IoC容器中,那么很多问题都交给了IoC容器来处理,不需要我们去关心对象的创建问题、依赖问题。这样就很大程度上简化了程序的开发。

🙎‍♂️面试官:什么是Spring Bean?

🙋‍♂答:

Spring Bean就是IoC容器所要管理的对象。通过注解的方式,我们可以告诉IoC容器管理什么对象。

Spring装配对象的四个注解:

  • @Component(组件):装配普通组件到IOC中。

  • @Repository(仓库):装配持久化层到IOC中。

  • @Service(业务):装配业务逻辑层到IOC中。

  • @Controller(控制):装配控制层/表示层组件到IOC中。

🙎‍♂️面试官:Bean的作用域?

🙋‍♂答:

Bean的作用域定义了Bean的生命周期和可见性。我们可以使用@Scope注解管理Bean的作用域。Bean有四个常用的作用域:

  • singleton【默认值】:是对单例设计模式的应用,随着IoC容器的创建而创建,随着容器的销毁而销毁。在这过程中,只会创建一个Bean对象。
  • prototype:每次请求创建一个对象,每次通过容器获取Bean时,都会返回一个新的对象。在使用Prototype作用域时,Spring不会对Bean的生命周期进行管理,需要手动处理Bean的销毁。
  • request:在一个HTTP请求中,Spring容器创建一个Bean对象;请求关闭,Bean也会被销毁。
  • session:在同一个HTTP会话中,即使存在多次请求,Spring容器也只会创建一个Bean对象;关闭浏览器,Bean实例被销毁。
    因为cookie丢失,由于session是由cookie来维护的,所以会话信息也会丢失。

🙎‍♂️面试官:Bean的生命周期?

🙋‍♂答:

  1. 实例化:Spring容器根据Bean的定义来进行实例化。可以通过构造函数实例化或通过工厂方法创建实例。
  2. 属性赋值:Spring会通过依赖注入的方法为Bean注入初始值。
  3. 初始化:调用Bean的初始化回调方法。可以使用@PostConstruct注解标注自定义的初始化方法。
  4. 使用:Bean已经被实例化,可以使用。
  5. 销毁:可以使用@PreDestroy注解标注自定义的销毁方法。

🙎‍♂️面试官:单例Bean的线程安全问题了解吗?

🙋‍♂答:

大部分的Bean都是没有实例变量的,比如Dao、Service。但是如果在Bean中定义成员变量,在多线程操作Bean时就可能出现线程安全问题。可以用以下解决方案:

  1. 避免定义成员变量。
  2. 使用ThreadLocal,ThreadLoacl是线程隔离的,每个线程都有自己的副本,可以防止多线程操作共享变量带来的问题。

项目中的HostHolder用到了ThreadLocal。

🙎‍♂️面试官:@Component 和 @Bean 注解的区别是什么?

🙋‍♂答:

  • 作用的位置不同。@Component注解作用于类,@Bean注解作用于方法。

  • 装配对象到IoC容器的方式不同

    • @Component通过组件扫描来自动检测和装配到Spring容器中。
    • @Bean注解标识的方法Spring只会调用一次,用来产生一个Bean对象。随后Spring将会将这个Bean对象放在自己的IOC容器中。
  • 在使用第三方类库中的类要装配到Spring容器时只能使用@Bean注解。

    • 比如项目中用来操作Redis数据库的RedisTemplate就是使用@Bean注解注入的。

🙎‍♂️面试官:项目中是怎么实现依赖注入的?

🙋‍♂答:

使用Spring的注解@Autowire实现依赖注入,比如我们的项目中,Controller层依赖于Service层,Service层依赖于Dao层。那么我们就可以使用@Autowire实现依赖注入,将对应的Bean对象注入到我们的属性中,之后直接使用这个属性即可。这样我们就可以实现层与层之间的解耦,减少对象之间的依赖关系。

🙎‍♂️面试官:@Autowired 和 @Resource 的区别是什么?

🙋‍♂答:

  • 两者的依赖注入方式不同。
    • @Autowired默认注入方式为byType,根据类型进行匹配。但是如果一个接口存在多个实现类,就会使用byName进行匹配,名称通常就是类名首字母小写。建议在使用时通过@Qualifier来显式指定要匹配的类名,而不适用变量名。
    • @Resource默认注入方式为 byName。如果无法通过名称匹配到对应的 Bean 的话,注入方式会变为byType。 可以通过 name 属性来显式指定名称。

Spring AOP

🙎‍♂️面试官:说说自己对于AOP的了解?

🙋‍♂答:

Spring AOP 可以对某一个方法进行横向的拓展,能够将与业务无关的代码逻辑封装起来,有利于未来的可拓展性和可维护性。比如日志管理,统一异常处理都运用了AOP的思想。

举例:
项目中的统一记录日志,先将所有的Service下的方法都作为切入点。使用@Before注解,在进入切入点之前进行通知,也就是对方法进行了横向的扩展。这样就在每个service类中的方法调用前,都记录了日志。

🙎‍♂️面试官:Spring AOP 和 AspectJ AOP 有什么区别?

🙋‍♂答:

Spring AOP 属于运行时增强,而 AspectJ 是编译时增强。 Spring AOP 基于代理(Proxying),而 AspectJ 基于字节码操作(Bytecode Manipulation)。

AspectJ是生态最完整的AOP框架,并且功能相比Spring AOP 很强大。

🙎‍♂️面试官:AspectJ 定义的通知类型有哪些?

🙋‍♂答:

Before(前置通知):目标对象的方法调用之前触发

After (后置通知):目标对象的方法调用之后触发

AfterReturning(返回通知):目标对象的方法调用完成,在返回结果值之后触发

AfterThrowing(异常通知) :目标对象的方法运行中抛出 / 触发异常后触发。AfterReturning 和 AfterThrowing 两者互斥。如果方法调用成功无异常,则会有返回值;如果方法抛出了异常,则不会有返回值。

Around (环绕通知):编程式控制目标对象的方法调用。环绕通知是所有通知类型中可操作范围最大的一种,因为它可以直接拿到目标对象,以及要执行的方法,所以环绕通知可以任意的在目标对象的方法调用前后搞事,甚至不调用目标对象的方法

Spring MVC

🙎‍♂️面试官:说说自己对于Spring MVC的了解?

🙋‍♂答:

使用Spring MVC 与Spring框架集成,可以进行更加简单的Web层开发。其核心思想是通过将业务逻辑、数据进行分离来组织代码。

Spring MVC 下我们一般把后端项目分为 Service 层(处理业务)、Dao 层(数据库操作)、Entity 层(实体类)、Controller 层(控制层,返回数据给前台页面)。

MVC : Model(模型层)-View(视图层)- Controller(控制层) ,指的是一种设计模式。

🙎‍♂️面试官:Spring MVC 的核心组件?

🙋‍♂答:

DispatcherServlet核心的中央处理器,负责接收请求、分发,并给予客户端响应。

HandlerMapping处理器映射器,根据 uri 去匹配查找能处理的 Handler ,并会将请求涉及到的拦截器和 Handler 一起封装。

HandlerAdapter处理器适配器,根据 HandlerMapping 找到的 Handler ,适配执行对应的 Handler;

Handler(Controller)请求处理器,处理实际请求的处理器。

ViewResolver视图解析器,根据 Handler 返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 DispatcherServlet 响应客户端。

🙎‍♂️面试官:Spring MVC 的工作流程?

🙋‍♂答:
【面试篇】SpringIoC、AOP、MVC面试实战-LMLPHP

  1. 该请求到达DispatcherServlet,它是Spring MVC框架的核心控制器。
  2. DispatcherServlet通过调用HandlerMapping 解析器来根据url来确定请求交给哪个处理器处理。找到处理器后,将请求和相应的上下文信息封装为HandlerExecutionChain 对象。
    • HandlerExecutionChain:请求处理器的执行链对象。Controller + Interceptor
  3. DispatcherServlet调用 HandlerAdapter ,会根据 HandlerExecutionChain ,适配执行对应的 Hanlder;
  4. Controller (处理器)完成对用户请求的处理后,会返回一个ModelAndView对象给DispatcherServlet。
    • 这个对象中包含数据模型以及对应的视图信息。数据模型表示控制器向视图传递的数据,视图信息表示用于呈现响应的视图的名称或路径。
  5. ViewResolver(视图解析器)会根据逻辑上的View(逻辑视图) 查找到实际的View(物理视图)。
  6. DispatcherServlet会把返回的Model传给View进行视图渲染。
  7. 最后把View返回给浏览器。

如果需要,Spring 还会应用拦截器和过滤器来处理请求。拦截器可以在请求到达处理器之前或之后执行一些操作,过滤器可以在请求到达 DispatcherServlet 之前或之后执行一些操作。

比如:使用SpringSecurity Filter,过滤器可以在请求到达DispatcherServlet之前执行一些操作。可以进行一个权限的校验。

完。

05-24 00:29