深圳做网站要多少,电商网站运营策划,网站排行查询,jquery素材网站1. Spring, Spring MVC, SpringBoot是什么关系#xff1f;
Spring 包含了多个功能模块#xff0c;Spring MVC是其中一个模块#xff0c;专门处理Web请求。Spring Boot 只是简化了配置#xff0c;如果需要构建 MVC 架构的 Web 程序#xff0c;还是需要使用 Spring MVC 作为…1. Spring, Spring MVC, SpringBoot是什么关系Spring 包含了多个功能模块Spring MVC是其中一个模块专门处理Web请求。Spring Boot 只是简化了配置如果需要构建 MVC 架构的 Web 程序还是需要使用 Spring MVC 作为 MVC 框架只是说 Spring Boot 简化了 Spring MVC 的很多配置真正做到开箱即用。2. 谈一谈对Spring IoC的理解IoCInversion of Control:控制反转 将原本在程序中手动创建对象的控制权交由 Spring 框架来管理。为什么叫控制反转控制指的是对象创建实例化、管理的权力反转控制权交给外部环境Spring 框架、IoC 容器3. Component 和 Bean 的区别Component 注解作用于类而Bean注解作用于方法。当我们引用第三方库中的类需要装配到 Spring容器时则只能通过 Bean来实现。4. Autowired 和 Resource 的区别Autowired属于 Spring 内置的注解默认的注入方式为byType根据类型进行匹配也就是说会优先根据接口类型去匹配并注入 Bean 接口的实现类。 当一个接口存在多个实现类的话byType这种方式就无法正确注入对象了因为这个时候 Spring 会同时找到多个满足条件的选择默认情况下它自己不知道选择哪一个。这种情况下注入方式会变为byName根据名称进行匹配这个名称通常就是类名首字母小写。通过 Qualifier 注解可以来显式指定名称而不是依赖变量的名称。Resource属于 JDK 提供的注解默认注入方式为byName。如果无法通过名称匹配到对应的 Bean 的话注入方式会变为byType。Resource 有两个比较常用的属性name名称、type类型。如果仅指定 name 属性则注入方式为byName如果仅指定type属性则注入方式为byType如果同时指定name 和type属性不建议这么做则注入方式为byTypebyName。5. 注入Bean的方法有哪些构造函数注入通过类的构造函数来注入依赖项。Setter 注入通过类的 Setter 方法来注入依赖项。Field字段 注入直接在类的字段上使用注解如 Autowired 或 Resource来注入依赖项。6. 为什么Spring 官方推荐构造函数注入依赖完整性确保所有必需依赖在对象创建时就被注入避免了空指针异常的风险。不可变性有助于创建不可变对象提高了线程安全性。初始化保证组件在使用前已完全初始化减少了潜在的错误。测试便利性在单元测试中可以直接通过构造函数传入模拟的依赖项而不必依赖 Spring 容器进行注入。篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho7. Bean 的作用域有哪些singleton: IoC 容器中只有唯一的 bean 实例。Spring 中的 bean 默认都是单例的是对单例设计模式的应用。prototype: 每次获取都会创建一个新的 bean 实例。也就是说连续 getBean() 两次得到的是不同的 Bean 实例。request: 每一次 HTTP 请求都会产生一个新的 bean该 bean 仅在当前 HTTP request 内有效。session: 每一个 HTTP Session 会产生一个新的 bean该 bean 仅在当前 HTTP session 内有效。8. Bean 是线程安全的吗Spring 框架中的 Bean 是否线程安全取决于其作用域和状态。几乎所有场景的 Bean 作用域都是使用默认的singleton 重点关注 singleton 作用域即可。prototype 作用域下每次获取都会创建一个新的 bean 实例不存在资源竞争问题所以不存在线程安全问题。singleton 作用域下IoC 容器中只有唯一的 bean 实例可能会存在资源竞争问题取决于 Bean 是否有状态。如果这个 bean 是有状态的话那就存在线程安全问题有状态 Bean 是指包含可变的成员变量的对象。9. Bean 的生命周期了解吗Bean的生命周期从Spring容器启动开始首先根据配置或注解扫描获取Bean的定义信息随后通过反射实例化对象并填充属性完成依赖注入。如果Bean实现了诸如BeanNameAware等Aware接口容器会在此阶段回调相关方法使其感知自身信息。接下来BeanPostProcessor的postProcessBeforeInitialization方法被调用执行初始化前的自定义逻辑例如处理PostConstruct注解的方法。随后容器触发初始化回调包括InitializingBean接口的afterPropertiesSet方法或通过XML、注解定义的初始化方法。BeanPostProcessor的postProcessAfterInitialization在此之后执行常见于生成AOP代理对象等增强处理。此时Bean已就绪可被应用程序使用。当容器关闭时销毁流程启动依次执行PreDestroy注解的方法、DisposableBean接口的destroy方法或配置的销毁方法最终完成Bean的资源释放与生命周期终结。10. 如何解决 Spring 中的循环依赖问题Spring通过三个缓存层级解决单例Bean的循环依赖问题缓存名称描述singletonObjects一级缓存存放完全初始化好的Bean成品对象。earlySingletonObjects二级缓存存放早期暴露的Bean已实例化但未填充属性未初始化。singletonFactories三级缓存存放Bean的工厂对象ObjectFactory用于生成早期引用。以A依赖BB依赖A为例创建Bean A实例化A调用A的构造函数创建对象此时对象未填充属性未初始化。将A的工厂对象放入三级缓存singletonFactories用于后续生成早期引用。填充A的属性发现需要注入B。创建Bean B实例化B调用B的构造函数创建对象。将B的工厂对象放入三级缓存。填充B的属性发现需要注入A。解决B对A的依赖从三级缓存中获取A的工厂对象singletonFactories生成A的早期引用通过getEarlyBeanReference方法。这一步是整合了第一步那个实例化但是没在任何缓存里的A对象给他变成了半成品代理对象如果A有被代理的话将A的早期引用存入二级缓存earlySingletonObjects并从三级缓存中删除A的工厂。将A的早期引用注入到B中完成B的属性填充和初始化。将初始化后的B存入一级缓存singletonObjects。完成A的创建从一级缓存中获取已初始化的B注入到A中。完成A的属性填充和初始化。将A存入一级缓存并从二级缓存中删除A的早期引用。我直接在实例化的时候判断A有没有代理如果有的话我直接把代理对象放到二级缓存里不行吗这样就不用三级缓存了代理对象应该在bean实例化→属性填充→初始化做完之后才去生成的bean的生命周期假设没有出现循环依赖bean能通过正常的生命周期生成代理我们直接在bean没完成初始化前就生成代理对象了就打乱了bean的生命周期了。通过三级缓存可以推迟bean的早期引用暴露也就是说要不要提前生成代理对象这个事情推迟到循环依赖真正发生的时候。如果真发生了循环依赖B才会调用getEarlyBeanReference方法生成A的代理如果没循环依赖的话在二级缓存正常放填充好属性的A对象的就不用提前把A的代理放二级缓存了。注意点仅支持单例Bean的循环依赖原型Prototype作用域的Bean无法通过缓存解决循环依赖Spring会直接抛出异常。构造器注入无法解决循环依赖如果循环依赖通过构造函数参数注入而非Setter方法或字段注入Spring无法提前暴露对象会抛出BeanCurrentlyInCreationException。解释如果两个Bean都是原型模式的话那么创建A1需要创建一个B1创建B1的时候要创建一个A2创建A2又要创建一个B2,创建B2又要创建一个A3创建A3又要创建一个B3循环依赖就没办法解决了。如果A和B的依赖都是通过构造器注入那连一个半成品对象都创建不出来也没办法解决循环依赖11. Lazy能解决循环依赖问题吗在一定程度上是能解决的Spring 创建 A 时发现它依赖 B但 B 被标记为 Lazy。不立即初始化 B而是注入一个 B 的代理对象由 Spring 动态生成。当 A 的方法首次调用 b.xxx() 时代理对象才会触发 B 的实际初始化。此时 B 初始化时再去注入 A由于 A 已经存在循环依赖被解开。12. Spring 动态代理默认用哪一种Spring Boot 2.x 及以上版本默认启用了 proxyTargetClasstrue因此无论目标类是否实现接口统一使用 CGLIB 生成代理。动态代理的使用13. Spring中拦截器和过滤器的区别过滤器Filter是Servlet规范的一部分其作用范围覆盖整个Web应用能够处理所有进入Servlet容器的请求例如修改请求参数、设置字符编码或实现全局安全控制。它的执行时机在请求到达DispatcherServlet之前因此可以作用于静态资源等非Spring管理的请求。拦截器Interceptor是Spring MVC框架提供的组件其实现依赖于HandlerInterceptor接口通过Spring的配置类注册到拦截器链中。它的核心作用范围集中在Spring管理的控制器Controller层能够在请求进入具体Controller方法前preHandle、方法执行后视图渲染前postHandle以及整个请求完成后afterCompletion这三个关键节点插入逻辑。所以拦截器更适合处理与业务紧密相关的操作例如基于会话的权限校验、日志记录或接口性能监控。从执行顺序上看整体上过滤器的处理会先于拦截器完成。过滤器更偏向底层请求的通用处理而拦截器则聚焦于Spring MVC流程中的业务逻辑增强。HTTP Request → Servlet Filter (过滤请求) → DispatcherServlet → Interceptor.preHandle() → Controller → Interceptor.postHandle() → Interceptor.afterCompletion()运行项目并下载源码bash123456714. Spring Boot的配置优先级从高到低命令行参数–keyvaluejava系统属性-Dkeyvalueapplication.propertiesapplication.yml15. Spring Boot 自动配置如何实现的https://blog.csdn.net/fim77/article/details/14645903316. PathVariable 和 RequestParam 的区别PathVariable用于获取路径参数/users/{id} → /users/123RequestParam用于获取查询参数。/users?id12317. Spring MVC的工作流程图片来自面试鸭用户https://www.mianshiya.com/user/181599500555137433718. Spring Boot 支持哪些嵌入式 web 容器SpringBoot提供了三种内嵌Web容器分别为Tomcat、Jetty和Undertow。当你在项目中引入spring-boot-starter-web这个起步依赖时Spring Boot默认会包含并启用Tomcat作为内嵌Servlet容器。如果你想使用Jetty或Undertow需要在构建文件如Maven的pom.xml或Gradle 的build.gradle中从spring-boot-starter-web 中排除默认的Tomcat 依赖spring-boot-starter-tomcat添加你想使用的容器对应的Starter 依赖例如spring-boot-starter-jetty 或spring-boot-starter-undertow19. 介绍一下SpringBootApplication注解SpringBootApplication是SpringBoot项目的核心注解通常用于标记应用程序的主类即包含main方法的类。它的主要作用是一站式地启用SpringBoot的关键特性简化项目的初始配置。SpringBootConfiguration继承自 Configuration标记当前类为配置类允许通过 Bean 注解定义和注册 Bean。EnableAutoConfiguration启用 Spring Boot 的自动配置机制。根据项目依赖中META-INF/下后缀为.imports 文件加载预定义的配置类结合条件注解如 ConditionalOnClass自动配置 Spring 应用所需的 Bean。ComponentScan默认扫描当前类所在包及其子包下的组件并将它们注册为 Spring Bean。20. Spring Boot 常用的两种配置文件是什么application.properties采用标准的JavaProperties文件格式即键值对keyvalue的形式每一行定义一个配置项。server.port8080 spring.datasource.urljdbc:mysql://localhost:3306/mydb运行项目并下载源码yml12application.yml或yaml采用YAMLYAMLAin’tMarkupLanguage格式这是一种层级化、以缩进表示结构的数据序列化语言。相比.properties文件YAML 格式通常更易于阅读尤其是在配置项较多或具有嵌套结构时结构更清晰。并且对于具有共同前缀的配置项YAML可以通过层级嵌套避免重复书写前缀使配置更简洁。server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/mydb运行项目并下载源码yml1234521. 如何使用Spring Boot实现全局异常处理在 Spring Boot 中可以通过 ControllerAdvice 和 ExceptionHandler注解实现全局异常处理。RestControllerAdvice public class GlobalExceptionHandler { // 处理自定义异常 ExceptionHandler(BusinessException.class) public ResponseEntityErrorResponse handleBusinessException(BusinessException ex) { ErrorResponse error new ErrorResponse(ex.getCode(), ex.getMessage()); return ResponseEntity.status(ex.getHttpStatus()).body(error); } // 处理所有未捕获的异常 ExceptionHandler(Exception.class) public ResponseEntityErrorResponse handleGenericException(Exception ex) { ErrorResponse error new ErrorResponse(ERROR_500, 系统内部错误); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error); } }运行项目并下载源码java运行22. Spring 中如何实现定时任务多节点重复执行如何避免在 Spring Boot 主类或配置类上添加EnableSchedulingSpringBootApplication EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }运行项目并下载源码java运行使用Scheduled注解标记方法支持 cron、fixedRate、fixedDelay 等参数Component public class MyScheduledTasks { // 每 5 秒执行一次 Scheduled(fixedRate 5000) public void doTask() { System.out.println(执行定时任务: new Date()); } }运行项目并下载源码java运行Spring Task 在多节点部署时如果不采取措施每个节点都会执行相同的定时任务导致重复执行。这主要是因为每个节点上都运行着独立的 Spring 容器每个容器都拥有自己的定时任务调度器并独立地根据配置的时间触发任务互不干扰。如果多个节点的配置相同就会导致同一任务在多个节点上并发执行。这种情况不仅浪费资源还可能导致数据不一致、资源竞争等问题最终导致业务逻辑错误例如重复处理相同的数据、发送重复的通知。解决方法分布式锁分布式任务调度工具如XXL-JOB篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho23. 你的项目是如何统一返回结果的code: 状态码遵循HTTP状态码规范并扩展业务状态码message: 对状态的描述信息data: 实际返回的业务数据timestamp: 响应时间戳手动显式封装GetMapping(/{id}) public ResultUser getUser(PathVariable Long id) { User user userService.getUserById(id); return Result.success(user); }运行项目并下载源码java运行12345自动封装RestControllerAdvice public class ResponseAdvice implements ResponseBodyAdviceObject { Override public boolean supports(MethodParameter returnType, Class? extends HttpMessageConverter? converterType) { // 判断是否需要包装 return !returnType.getParameterType().equals(Result.class); } Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class? extends HttpMessageConverter? selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { return Result.success(body); } }运行项目并下载源码java运行24. 什么是Spring Boot Starters?Spring Boot Starters 是一组便捷的依赖描述符它们预先打包了常用的库和配置。当我们开发 Spring 应用时只需添加一个 Starter 依赖项即可自动引入所有必要的库和配置而无需手动逐一添加和配置相关依赖。这种机制显著简化了开发过程特别是在处理复杂项目时尤为高效。通过添加一个简单的Starter 依赖开发者可以快速集成所需的功能避免了手动管理多个依赖的繁琐和潜在错误。这不仅节省了时间还减少了配置错误的风险从而提升了开发效率。25. Spring Boot 的主要优点?显著提升开发效率:Spring Boot 通过自动配置、起步依赖(Starters)和其他开箱即用的功能极大地减少了项目初始化、配置编写和样板代码的工作量使开发者能更快地构建和交付应用。与 spring 生态系统的无缝集成:作为 Spring 家族的一员Spring Boot 能够方便地整合 Spring 框架下的其他成熟模块(如 Spring Data、Spring Security、Spring Batch 等)充分利用 Spring 强大的生态系统简化整合工作。强大的自动配置能力:遵循“约定优于配置”的原则Spring Boot 能够根据项目依赖自动配置大量的常见组件(如数据源、Web 容器、消息队列等)提供合理的默认设置。同时也允许开发者根据需要轻松覆盖或定制配置极大减少了繁琐的手动配置工作。内嵌 Web 服务器支持:Spring Boot 自带内嵌的 HTTP服务器(如 Tomcat、Jetty)开发者可以像运行普通 Java 程序一样运行 Spring Boot 应用程序极大地简化了开发和测试过程。适合微服务架构:Spring Boot 使得每个微服务都可以独立运行和部署简化了微服务的开发、测试和运维工作成为构建微服务架构的理想选择。提供强大的构建工具支持:Spring Boot为常用的构建工具(如 Maven和 Gradle)提供了专门的插件简化了项目的打包(如创建可执行JAR)、运行、测试以及依赖管理等常见构建任务丰富的监控和管理功能:通过 Spring Boot Actuator 模块可以轻松地为应用添加生产级的监控和管理端点方便了解应用运行状况、收集指标、进行健康检查等。26. Spring Boot 是如何通过 main 方法启动 web 项目的https://www.mianshiya.com/bank/1797452903309508610/question/1846441429268488194#heading-1427. 如何在 Spring Boot 中读取配置信息使用Value注解// 直接注入配置项支持默认值如未配置则使用默认值 Value(${book.author:defaultAuthor}) private String author;运行项目并下载源码java运行123使用ConfigurationProperties注解# 配置文件 application.yml book: name: 三国演义 author: 罗贯中 price: 30 chapters: - 第一章 - 第二章运行项目并下载源码ymlComponent ConfigurationProperties(prefix book) public class BookProperties { private String name; private String author; private int price; private ListString chapters; }运行项目并下载源码java运行使用Environment接口Autowired private Environment env; public String getAppInfo() { String appName env.getProperty(app.name); String maxRetry env.getProperty(app.max-retry, defaultRetry); }运行项目并下载源码java运行28. Spring 事务中哪几种事务传播行为?总共有7种常用的就前两种PROPAGATION_REQUIRED默认如果当前存在事务则加入该事务否则新建一个事务。所有嵌套方法共享同一个事务任一方法抛出异常会导致整个事务回滚。PROPAGATION_REQUIRES_NEW无论当前是否存在事务都新建一个独立事务。内层事务与外层事务完全隔离外层事务回滚不影响内层事务。PROPAGATION_NESTED如果当前存在事务则在当前事务内嵌套一个子事务否则创建新事务。子事务是父事务的一部分但可以独立回滚。子事务回滚不影响父事务需捕获异常父事务回滚则子事务也会回滚。PROPAGATION_MANDATORY必须在一个已存在的事务中运行否则抛出异常。PROPAGATION_SUPPORTS如果当前存在事务则加入该事务否则以非事务方式运行。PROPAGATION_NOT_SUPPORTED以非事务方式运行如果当前存在事务则挂起。PROPAGATION_NEVER以非事务方式运行如果当前存在事务则抛出异常。29. Spring 中BeanFactory 和 FactoryBean是什么BeanFactory是Spring框架的核心接口作为IoC容器的基础负责管理Bean的生命周期包括创建、配置和装配对象。FactoryBean是一个特殊的Bean可以在运行时根据特定条件或需求通过getObject()方法动态控制Bean的实例化过程在容器中通过名称前加符号区分获取FactoryBean本身与其生产的对象。30. ApplicationContext是什么ApplicationContext是Spring框架的核心容器接口它作为高级容器不仅继承了BeanFactory的基础功能来管理和配置Bean还扩展了众多企业级特性。它整合了资源加载、国际化支持、事件发布与监听机制同时支持AOP、事务管理等高级功能。31. Spring Boot 如何做请求参数校验验证请求体在 DTO 类上使用校验注解public class UserDTO { Size(min 2, max 20, message 用户名长度必须在2-20之间) private String username; }运行项目并下载源码java运行在 Controller 中使用 Valid 注解触发校验Validated也行PostMapping(/users) public ResponseEntity? createUser(RequestBody Valid UserDTO userDTO) { // 业务逻辑 return ResponseEntity.ok(用户创建成功); }运行项目并下载源码java运行验证请求参数直接在方法参数上使用校验注解GetMapping(/users/{id}) public ResponseEntity? getUserById(PathVariable Min(1) Long id) { // 业务逻辑 return ResponseEntity.ok(...); }运行项目并下载源码java运行需要在 Controller 类上添加 Validated 注解只能在类上添加这个才有用RestController Validated public class UserController { // ... }运行项目并下载源码java运行补充分组校验public class UserDTO { NotBlank(message 用户名不能为空, groups {CreateGroup.class, UpdateGroup.class}) private String username; Email(message 邮箱格式不正确, groups CreateGroup.class) // 仅创建时需要校验邮箱 private String email; NotNull(message ID不能为空, groups UpdateGroup.class) // 仅更新时需要校验ID private Long id; // Getter 和 Setter }运行项目并下载源码java运行PostMapping(/users) public ResponseEntity? createUser(RequestBody Validated(CreateGroup.class) UserDTO userDTO) { return ResponseEntity.ok(创建用户校验通过); }运行项目并下载源码java运行32. Spring Boot 如何处理跨域请求篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho33. Spring Boot 如何实现异步处理主要有四种方式来实现异步处理使用 Async注解使用 CompletableFuture使用Scheduled注解使用线程池34. 说说对 Spring 中事件机制的理解Spring 的事件机制是一种基于观察者模式设计的解耦通信方式允许组件在特定动作发生时通过事件传递信息而不必直接依赖彼此。开发者可以自定义继承 ApplicationEvent 的事件类由事件发布者通过 ApplicationEventPublisher 触发事件而监听者通过实现 ApplicationListener 接口或使用 EventListener 注解来捕获并处理事件。这种机制默认以同步方式运行但结合 Async 或自定义线程池可支持异步处理提升系统响应能力。例如用户注册成功后发布事件由监听器异步发送邮件或初始化数据避免主流程阻塞。35. Spring 中如何配置多数据源36. Spring 中有哪些设计模式工厂模式Factory Pattern作用隐藏对象创建细节由容器统一管理 Bean 的生命周期。单例模式Singleton PatternSpring 默认的 Bean 作用域为单例singleton确保每个容器中一个 Bean 仅有一个实例。作用节省资源保证全局一致性。原型模式Prototype PatternBean 的作用域设为 prototype 时每次请求都会创建新实例如 Scope(“prototype”)。代理模式Proxy PatternSpring AOP面向切面编程通过动态代理实现横切关注点如事务、日志。模板方法模式Template Method PatternJdbcTemplate、RestTemplate 等模板类封装通用流程消除重复代码观察者模式Observer Pattern核心应用Spring 事件驱动模型ApplicationEvent 和 ApplicationListener。适配器模式Adapter Pattern统一接口兼容不同实现。装饰者模式Decorator PatternHttpServletRequestWrapper 包装 HTTP 请求增强其行为如缓存请求体。策略模式Strategy PatternSpring MVC 的 HandlerMapping 根据请求匹配不同策略的处理器。委派模式Delegate PatternDispatcherServlet 将请求分发给不同的处理器如 Controller、Handler。建造者模式Builder Pattern分步构建复杂对象。责任链模式Chain of ResponsibilitySpring Security 的过滤器链FilterChainProxy每个过滤器依次处理请求。