• Spring 面试题


    Spring IOC

    IOC 控制反转,是指将对象控制权转移到spring容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系。IOC让对象的创建不用去new了,可以由spring自动生产,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法。

    Spring AOP

    面向切面,作为面向对象一种补充。将那些与业务无关公共行为和逻辑,抽取并封装为一个可重用的模块,减少系统的重复代码,降低模块间的耦合度,提高系统的可维护性。可用于权限认证、日志、事务处理等。

    AOP通知类型顺序

    aop环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别:

    1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知   是不能决定的,他们只是在方法的调用前后执行通知而已,即目标方法肯定是要执行的。

    2)  环绕通知可以控制返回对象,即你可以返回一个与目标对象完全不同的返回值,虽然这很危险,但是你却可以办到。而后置方法是无法办到的,因为他是在目标方法返回值后调用

    Spring 事务失效场景

    1.抛出检查异常(默认只对RuntimeException 和 Error 有效)

    2.try-catch

    3.aop切面

    4.非public方法导致事务失效

    5.父子容器导致事务失效

    6.调用本类方法导致传播行为失效(本类方法调用不经过代理)

    7. @Transational 没有保证原子行为,select方法没有阻塞

    8.@Transational 方法导致的synchronized失效,synchronized仅保证目标方法的原子性,没有环绕commit等操作

    完整内容请查看:Java 面试指南 | JavaGuide

    Spring bean 的生命周期

    Bean的生命周期概括起来有四个阶段:实例化 -> 属性赋值 -> 初始化 -> 销毁

    在这里插入图片描述

    Spring Bean的生命周期(一图看懂bean生命周期)_尘风-随手记的博客-CSDN博客_bean生命周期图

    Spring 常用扩展接口

    1. InitializingBean接口
    2. DisposableBean接口
    3. ApplicationContextAware接口
    4. BeanFactoryAware接口
    5. FactoryBean接口
    6. BeanPostProcessor接口
    7. InstantiationAwareBeanPostProcessor接口
    8. BeanFactoryPostProcessor接口

    什么是 Spring 框架?

    Spring 是一款开源的轻量级 Java 开发框架,旨在提高开发人员的开发效率以及系统的可维护性。

    Spring 最核心的思想就是不重新造轮子,开箱即用,提高开发效率。

    Spring 提供的核心功能主要是 IoC 和 AOP。

    Spring,Spring MVC,Spring Boot 之间什么关系?

    Spring 包含了Spring-Core(主要提供 IoC 依赖注入功能的支持) 模块, Spring MVC的功能实现都需要依赖于该模块。

    Spring MVC 是 Spring 中的一个很重要的模块,主要赋予 Spring 快速构建 MVC 架构的 Web 程序的能力。MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。

    Spring Boot 旨在简化 Spring 开发(减少配置文件,开箱即用!)。

    Spring IoC

    IoC(Inverse of Control:控制反转) 是一种设计思想。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。

    什么是 Spring Bean?

    Bean 代指的就是那些被 IoC 容器所管理的对象。

    配置元数据可以是 XML 文件、注解或者 Java 配置类。

    将一个类声明为 Bean 的注解有哪些?

    • @Component :通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用@Component 注解标注。
    • @Repository : 对应持久层即 Dao 层,主要用于数据库相关操作。
    • @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。
    • @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。

    @Component 和 @Bean 的区别是什么?

    • @Component 注解作用于类,而@Bean注解作用于方法。
    • @Component通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中
    • @Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean
    • @Bean 注解比 @Component 注解的自定义性更强,而且很多地方我们只能通过 @Bean 注解来注册 bean。比如当我们引用第三方库中的类需要装配到 Spring容器时,则只能通过 @Bean来实现。

    注入 Bean 的注解有哪些?

    Spring 内置的 @Autowired 以及 JDK 内置的 @Resource 和 @Inject 都可以用于注入 Bean。

    @Autowired 和 @Resource 的区别是什么?

    • @Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
    • Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
    • 当一个接口存在多个实现类的情况下,@Autowired 和@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显示指定名称,@Resource可以通过 name 属性来显示指定名称。

    Bean 的作用域有哪些?

    • singleton : IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的,是对单例设计模式的应用。
    • prototype : 每次获取都会创建一个新的 bean 实例。也就是说,连续 getBean() 两次,得到的是不同的 Bean 实例。
    • request (仅 Web 应用可用): 每一次 HTTP 请求都会产生一个新的 bean(请求 bean),该 bean 仅在当前 HTTP request 内有效。
    • session (仅 Web 应用可用) : 每一次来自新 session 的 HTTP 请求都会产生一个新的 bean(会话 bean),该 bean 仅在当前 HTTP session 内有效。
    • application/global-session (仅 Web 应用可用): 每个 Web 应用在启动时创建一个 Bean(应用 Bean),,该 bean 仅在当前应用启动时间内有效。
    • websocket (仅 Web 应用可用):每一次 WebSocket 会话产生一个新的 bean。

    Controller是单例还是多例?

    controller默认是单例的,正因为单例所以不是线程安全的。

    常见的有两种解决办法:

    1. 在 Bean 中尽量避免定义非静态的成员变量。
    2. 在类中定义一个 ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。

    Spring AoP

    AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

    Spring MVC 的核心组件有哪些?

    • DispatcherServlet :核心的中央处理器,负责接收请求、分发,并给予客户端响应。
    • HandlerMapping :处理器映射器,根据 uri 去匹配查找能处理的 Handler ,并会将请求涉及到的拦截器和 Handler 一起封装。
    • HandlerAdapter :处理器适配器,根据 HandlerMapping 找到的 Handler ,适配执行对应的 Handler
    • Handler :请求处理器,处理实际请求的处理器。
    • ViewResolver :视图解析器,根据 Handler 返回的逻辑视图 / 视图,解析并渲染真正的视图,并传递给 DispatcherServlet 响应客户端

     

    统一异常处理怎么做?

    注解的方式统一异常处理用到 @ControllerAdvice + @ExceptionHandler 这两个注解 。

    1. @ControllerAdvice
    2. @ResponseBody
    3. public class GlobalExceptionHandler {
    4. @ExceptionHandler(BaseException.class)
    5. public ResponseEntity handleAppException(BaseException ex, HttpServletRequest request) {
    6. //......
    7. }
    8. @ExceptionHandler(value = ResourceNotFoundException.class)
    9. public ResponseEntity handleResourceNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) {
    10. //......
    11. }
    12. }

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

    • 工厂设计模式 : Spring 使用工厂模式通过 BeanFactoryApplicationContext 创建 bean 对象。
    • 代理设计模式 : Spring AOP 功能的实现。
    • 单例设计模式 : Spring 中的 Bean 默认都是单例的。
    • 模板方法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
    • 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
    • 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。
    • 适配器模式 : Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller

    Spring 管理事务的方式有几种?

    • 编程式事务 : 在代码中硬编码(不推荐使用) : 通过 TransactionTemplate或者 TransactionManager 手动管理事务,实际应用中很少使用,但是对于你理解 Spring 事务管理原理有帮助。
    • 声明式事务 : 在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)

    Transactional 事务传播级别

    TransactionDefinition.PROPAGATION_REQUIRED

    @Transactional注解默认使用就是这个事务传播行为。如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

    如何对密码进行加密?

    Spring Security 提供了多种加密算法的实现,开箱即用,非常方便。这些加密算法实现类的父类是 PasswordEncoder ,如果你想要自己实现一个加密算法的话,也需要继承 PasswordEncoder

    1. public interface PasswordEncoder {
    2. // 加密也就是对原始密码进行编码
    3. String encode(CharSequence var1);
    4. // 比对原始密码和数据库中保存的密码
    5. boolean matches(CharSequence var1, String var2);
    6. // 判断加密密码是否需要再次进行加密,默认返回 false
    7. default boolean upgradeEncoding(String encodedPassword) {
    8. return false;
    9. }
    10. }

    @RestController

    @RestController注解是@Controller@ResponseBody的合集,表示这是个控制器 bean,并且是将函数的返回值直接填入 HTTP 响应体中,是 REST 风格的控制器。

    适合前后端分离项目

    处理常见的 HTTP 请求类型

    • GET :请求从服务器获取特定资源。举个例子:GET /users(获取所有学生)
    • POST :在服务器上创建一个新的资源。举个例子:POST /users(创建学生)
    • PUT :更新服务器上的资源(客户端提供更新后的整个资源)。举个例子:PUT /users/12(更新编号为 12 的学生)
    • DELETE :从服务器删除特定的资源。举个例子:DELETE /users/12(删除编号为 12 的学生)
    • PATCH :更新服务器上的资源(客户端提供更改的属性,可以看做作是部分更新),使用的比较少,这里就不举例子了。

    @GetMapping("users") 等价于@RequestMapping(value="/users",method=RequestMethod.GET)

    @RequestBody

    读取 Request 请求的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。

    1. @PostMapping("/sign-up")
    2. public ResponseEntity signUp(@RequestBody @Valid UserRegisterRequest userRegisterRequest) {
    3. userService.save(userRegisterRequest);
    4. return ResponseEntity.ok().build();
    5. }
    1. @Data
    2. @AllArgsConstructor
    3. @NoArgsConstructor
    4. public class UserRegisterRequest {
    5. @NotBlank
    6. private String userName;
    7. @NotBlank
    8. private String password;
    9. @NotBlank
    10. private String fullName;
    11. }

    @Value(常用)

    读取配置

    1. @Value("${wuhan2020}")
    2. String wuhan2020;

    为什么会出现跨域

    出于浏览器的同源策略

    什么是跨域

    当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

    SpringBoot解决跨域的三种方式

    第一种:添加@CrossOrigin注解

    1. @RestController
    2. @RequestMapping("index")
    3. public class IndexController {
    4. @GetMapping("/test")
    5. @CrossOrigin
    6. public String index() {
    7. return "hello world";
    8. }
    9. }

    第二种:添加CORS过滤器

    1. @Configuration
    2. public class CorsConfig {
    3. // 跨域请求处理
    4. @Bean
    5. public CorsFilter corsFilter() {
    6. CorsConfiguration config = new CorsConfiguration();
    7. //允许所有域名进行跨域调用
    8. config.addAllowedOrigin("*");
    9. //允许所有请求头
    10. config.addAllowedHeader("*");
    11. //允许所有方法
    12. config.addAllowedMethod("*");
    13. UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    14. source.registerCorsConfiguration("/**", config);
    15. return new CorsFilter(source);
    16. }
    17. }

    第三种:实现WebMvcConfigurer,重写addCorsMappings方法

    1. @Configuration
    2. public class CorsConfiguration implements WebMvcConfigurer{
    3. @Override
    4. public void addCorsMappings(CorsRegistry registry) {
    5. registry.addMapping("/**")
    6. .allowedOriginPatterns("*")
    7. .allowCredentials(true)
    8. .allowedMethods("GET", "POST", "DELETE", "PUT")
    9. .maxAge(3600);
    10. }
    11. }

  • 相关阅读:
    Linux知识点 -- 网络基础 -- 网络层
    FlashDB 移植
    高级数据结构与算法 | 布谷鸟过滤器(Cuckoo Filter):原理、实现、LSM Tree 优化
    JS流程控制语句_循环语句
    计算机Java项目|Springboot学生读书笔记共享
    vue3移动端项目构建,vue3+vant+vite+axios+pinia+sass
    C/C++基于词频的文件相似度
    快速写论文
    Linux系统下配置LEMP
    部分gcc预定义宏和函数栈帧的内存分布
  • 原文地址:https://blog.csdn.net/qq_29385297/article/details/126917383