Spring Boot 面试,一个问题就干趴下了!(下)

简介: 前些天栈长在Java技术栈微信公众号分享一篇文章:Spring Boot 面试,一个问题就干趴下了!,看到大家的留言很精彩,特别是说"约定大于配置"的这两个玩家。

image.png前些天栈长在Java技术栈微信公众号分享一篇文章:Spring Boot 面试,一个问题就干趴下了!,看到大家的留言很精彩,特别是说"约定大于配置"的这两个玩家。

image.png哈哈,上墙的朋友开不开森?


不错,约定优(大)于配置确实是 Spring Boot 整个框架的核心思想。


那么怎么理解约定优于配置呢?


百度百科定义:


约定优于配置(convention over configuration),也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。


总结就是两点:


1、约定一些推荐的默认配置;


2、开发人员只需要规定不符约定的部分;


这样做的好处就是,如果约定的默认配置符合我们的要求,省略即可,反之,再进行额外配置。


从 Spring Boot 中提供的默认的配置文件(application.properties/yml),再到默认值自动配置,都可以看出约定带来的便利,以及节省大量的配置。

来看下 Spring Boot 中一个自动配置的源码实例吧:

@Configuration@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class,        MultipartConfigElement.class })@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)@ConditionalOnWebApplication(type = Type.SERVLET)@EnableConfigurationProperties(MultipartProperties.class)public class MultipartAutoConfiguration {    private final MultipartProperties multipartProperties;    public MultipartAutoConfiguration(MultipartProperties multipartProperties) {        this.multipartProperties = multipartProperties;    }    @Bean    @ConditionalOnMissingBean    public MultipartConfigElement multipartConfigElement() {        return this.multipartProperties.createMultipartConfig();    }    @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)    @ConditionalOnMissingBean(MultipartResolver.class)    public StandardServletMultipartResolver multipartResolver() {        StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();        multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());        return multipartResolver;    }}@ConfigurationProperties(prefix = "spring.servlet.multipart", ignoreUnknownFields = false)public class MultipartProperties {    /**     * Whether to enable support of multipart uploads.     */    private boolean enabled = true;    /**     * Intermediate location of uploaded files.     */    private String location;    /**     * Max file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or     * kilobytes, respectively.     */    private String maxFileSize = "1MB";    /**     * Max request size. Values can use the suffixes "MB" or "KB" to indicate megabytes or     * kilobytes, respectively.     */    private String maxRequestSize = "10MB";    /**     * Threshold after which files are written to disk. Values can use the suffixes "MB"     * or "KB" to indicate megabytes or kilobytes, respectively.     */    private String fileSizeThreshold = "0";    /**     * Whether to resolve the multipart request lazily at the time of file or parameter     * access.     */    private boolean resolveLazily = false;    // get/set/etc..}@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class,        MultipartConfigElement.class })@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)@ConditionalOnWebApplication(type = Type.SERVLET)@EnableConfigurationProperties(MultipartProperties.class)public class MultipartAutoConfiguration {    private final MultipartProperties multipartProperties;    public MultipartAutoConfiguration(MultipartProperties multipartProperties) {        this.multipartProperties = multipartProperties;    }    @Bean    @ConditionalOnMissingBean    public MultipartConfigElement multipartConfigElement() {        return this.multipartProperties.createMultipartConfig();    }    @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)    @ConditionalOnMissingBean(MultipartResolver.class)    public StandardServletMultipartResolver multipartResolver() {        StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();        multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());        return multipartResolver;    }}@ConfigurationProperties(prefix = "spring.servlet.multipart", ignoreUnknownFields = false)public class MultipartProperties {    /**     * Whether to enable support of multipart uploads.     */    private boolean enabled = true;    /**     * Intermediate location of uploaded files.     */    private String location;    /**     * Max file size. Values can use the suffixes "MB" or "KB" to indicate megabytes or     * kilobytes, respectively.     */    private String maxFileSize = "1MB";    /**     * Max request size. Values can use the suffixes "MB" or "KB" to indicate megabytes or     * kilobytes, respectively.     */    private String maxRequestSize = "10MB";    /**     * Threshold after which files are written to disk. Values can use the suffixes "MB"     * or "KB" to indicate megabytes or kilobytes, respectively.     */    private String fileSizeThreshold = "0";    /**     * Whether to resolve the multipart request lazily at the time of file or parameter     * access.     */    private boolean resolveLazily = false;    // get/set/etc..}

这是一个文件上传的自动配置类,约定了:


1、约定了配置参数以 spring.servlet.multipart 前缀开始;


2、约定了很多默认配置,如:默认上传文件大小为 1M;


3、约定了所有的参数配置类名都是 *Properties;


4、约定了所有的自动配置类名都是 *AutoConfiguration;


5、约定了所有自动配置类配置在:/META-INF/spring.factories;


等等……


这样我们做一个文件上传操作几乎不用写任何配置了,除非满足不了需求,如:现在文件上传 1M 太小了,再加一行自定义配置即可,我们也可以按约定编写其他自动配置。


如果还不能理解,再来看 Maven 怎么做的,Maven 简直把约定大于配置的思想体现淋漓尽致。

image.png

image.pngMaven规定了哪个目录放什么文件,哪个文件做什么用,Maven会自动去处理,不需要我们再额外配置,其实我们也没有额外配置的需要,至少栈长我现在还没有遇到过。如果这些目录都让你来通过配置文件来配置,而每个项目配置的又不一样,你会不会想要崩溃?


其实这也不是新技术,只是一种设计思想,早在 JDK 1.5 中添加的《Java注解》就是很好的体现。


关于 “约定优于配置” 的思想,你还有什么好的想法,欢迎留言分享~


好了,今天的分享就到这里,关注Java技术栈微信公众号,在后台回复:boot,获取栈长整理的更多的 Spring Boot 教程,都是实战干货,以下仅为部分预览。


最近干货分享


面试问我 Java 逃逸分析,瞬间被秒杀了。。


到底什么是重入锁,拜托,一次搞清楚!


图解 Java 垃圾回收机制,写得非常好!


如何写出让同事无法维护的代码?


分享一份Java架构师学习资料


相关文章
|
5月前
|
设计模式 算法 架构师
京东二面:说下spring中常用的设计模式? (一个 深入骨髓的答案, 面试官跪下了)
京东二面:说下spring中常用的设计模式? (一个 深入骨髓的答案, 面试官跪下了)
京东二面:说下spring中常用的设计模式? (一个 深入骨髓的答案, 面试官跪下了)
|
10月前
|
前端开发 安全 Java
2025春招,Spring 面试题汇总
本文详细整理了2025年春招必备的Spring面试题,分为基础和高级两大部分,帮助求职者全面掌握Spring相关知识点,结合实际项目经验,提升面试成功率。内容涉及Spring框架、AOP、事务管理、数据库集成、Spring Boot、Spring Security、微服务架构等,助力你在春招中脱颖而出。
2185 0
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
347 2
|
10月前
|
XML Java 应用服务中间件
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
2579 17
Spring Boot 两种部署到服务器的方式
|
8月前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
353 0
|
11月前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
11月前
|
Java 数据库连接 Maven
最新版 | SpringBoot3如何自定义starter(面试常考)
在Spring Boot中,starter是一种特殊的依赖,帮助开发人员快速引入和配置特定功能模块。自定义starter可以封装一组特定功能的依赖和配置,简化项目中的功能引入。其主要优点包括模块化、简化配置、提高代码复用性和实现特定功能。常见的应用场景有短信发送模块、AOP日志切面、分布式ID生成等。通过创建autoconfigure和starter两个Maven工程,并编写自动配置类及必要的配置文件,可以实现一个自定义starter。最后在测试项目中验证其有效性。这种方式使开发者能够更便捷地管理和维护代码,提升开发效率。
1683 1
最新版 | SpringBoot3如何自定义starter(面试常考)
|
11月前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
11月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
276 2
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
519 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块