1、什么是 Spring Boot?
SpringBoot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。
2、为什么要用 Spring Boot?
Spring Boot 优点非常多,如:
独立运行
Spring Boot而且内嵌了各种servlet容器,Tomcat、Jetty等,现在不再需要打成war包部署到容器中,Spring Boot只要打成一个可执行的jar包就能独立运行,所有的依赖包都在一个jar包内。
简化配置
spring-boot-starter-web启动器自动依赖其他组件,简少了maven的配置。
自动配置
Spring Boot能根据当前类路径下的类、jar包来自动配置bean,如添加一个spring-boot-starter-web启动器就能拥有web的功能,无需其他配置。
无代码生成和XML配置
Spring Boot配置过程中无代码生成,也无需XML配置文件就能完成所有配置工作,这一切都是借助于条件注解完成的,这也是Spring4.x的核心功能之一。
应用监控
Spring Boot提供一系列端点可以监控服务及应用,做健康检测、注解配置监测。
3、Spring Boot 的核心配置文件有哪几个?它们的区别是什么?
Spring Boot 中有以下两种配置文件:
bootstrap (.yml 或者 .properties)
application (.yml 或者 .properties)
因此,对比 application 配置文件,bootstrap 配置文件具有以下几个特性:
boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载。
boostrap 里面的属性不能被覆盖。
bootstrap/ application 的应用场景:
application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。
bootstrap 配置文件有以下几个应用场景:
使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;
一些固定的不能被覆盖的属性;
一些加密/解密的场景。
4、Spring Boot 的配置文件有哪几种格式?它们有什么区别?
.properties 和 .yml,它们的区别主要是书写格式不同 如下:
1).properties
app.user.name=javastack
2).yml
app:user:name:javastack
注意: .yml 格式不支持 @PropertySource 注解导入配置
5、Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?
启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:
**@SpringBootConfiguration:**组合了 @Configuration 注解,实现配置文件的功能。
**@EnableAutoConfiguration:**打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。
@ComponentScan: Spring组件扫描。
6、开启 Spring Boot 特性有哪几种方式?
有以下两种方式:
继承spring-boot-starter-parent项目
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId><version>1.5.6.RELEASE</version></parent>
导入spring-boot-dependencies项目依赖
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.5.6.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependencies></dependencyManagement>
1. 属性覆盖只对继承有效
Spring Boot依赖包里面的组件的版本都是和当前Spring Boot绑定的,如果要修改里面组件的版本,只需要添加如下属性覆盖即可,但这种方式只对继承有效,导入的方式无效
<properties> <slf4j.version>1.7.25<slf4j.version></properties>
需要注意,要修改Spring Boot的依赖组件版本可能会造成不兼容的问题。
可以不需要,内置了 Tomcat/Jetty 等容器。
1)打包用命令或者放到容器中运行
2)用 Maven/Gradle 插件运行
3)直接执行 main 方法运行
9、Spring Boot 自动配置原理是什么?
Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射
org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>,ClassLoader)
代码如下:
public static List<String> loadFactoryNames(Class<?> factoryClass,ClassLoader classLoader){
String factoryClassName = factoryClass.getName();
try{
Enumeration<URL> urls = (classLoader!=null?classLoader.getResources(FACTORIES_RESOURCE_LOCATION):lassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List<String> result = new ArrayList<String>();
while(urls.hasMoreElements()){
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}catch(IOException ex){
throw new IllegalArgumentException("Unable to load ["+factoryClass.getName()+"] factories from location ["+FACTORIES_RESOURCE_LOCATION+"]",ex);
}
}
11、你如何理解 Spring Boot 中的 Starters?
Starters是什么:
Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找示例代码和依赖包。如你想使用Spring JPA访问数据库,只要加入spring-boot-starter-data-jpa启动器依赖就能使用了。Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。
Starters命名:
Spring Boot官方的启动器都是以spring-boot-starter-命名的,代表了一个特定的应用类型。第三方的启动器不能以spring-boot开头命名,它们都被Spring Boot官方保留。一般一个第三方的应该这样命名,像mybatis的mybatis-spring-boot-starter。
Starters分类:
Spring Boot应用类启动器
12、如何在 Spring Boot 启动的时候运行一些特定的代码?
如果你想在Spring Boot启动的时候运行一些特定的代码,你可以实现接口 ApplicationRunner 或者 CommandLineRunner ,这两个接口实现方式一样,它们都只提供了一个run方法。
CommandLineRunner: 启动获取命令行参数
ApplicationRunner: 启动获取应用启动的时候参数
使用方式:
或者这样
启动顺序:
如果启动的时候有多个ApplicationRunner和CommandLineRunner,想控制它们的启动顺序,可以实现 org.springframework.core.Ordered接口或者使用 org.springframework.core.annotation.Order注解
读取application文件:
在application.yml或者properties文件中添加:
info.address=USA
info.company=Spring
info.degree=high
一、@Value注解读取方式:
二、@ConfigurationProperties注解读取方式
读取指定文件:
资源目录下建立config/db-config.properties:
db.username=root
db.password=123456
一、@PropertySource+@Value注解读取方式:
注意:@PropertySource不支持yml文件读取。
二、@PropertySource+@ConfigurationProperties注解读取方式:
三、Environment读取方式:
以上所有加载出来的配置都可以通过Environment注入获取到
总结
从以上示例来看,Spring Boot可以通过@PropertySource,@Value,@Environment,@ConfigurationProperties来绑定变量。
4、Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
Spring Boot支持Java Util Logging,Log4j2,Lockback作为日志框架,如果你使用starters启动器,Spring Boot将使用Logback作为默认日志框架。无论使用哪种日志框架,Spring Boot都支持配置将日志输出到控制台或者文件中。
spring-boot-starter启动器包含spring-boot-starter-logging启动器并集成了slf4j日志抽象及Logback日志框架。
属性配置日志:
Spring Boot支持属性配置日志参数,这个不是很灵活,不细讲
既然默认自带了Logback框架,Logback也是最优秀的日志框架,往资源目录下创建一个logback-spring.xml即可。
强烈推荐使用logback-spring.xml作为文件名,因为logback.xml加载太早。
日志初始化在ApplicationContext创建之前,所以@PropertySources加载的配置是读取不到的,系统环境变量、Spring Environment及application,bootstrap配置文件中的信息可以读取到。
16、你如何理解 Spring Boot 配置加载顺序?
使用 Spring Boot 会涉及到各种各样的配置,如开发、测试、线上就至少 3 套配置信息了。Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发、测试、线上环境使用不同的配置。
在 Spring Boot 里面,可以使用以下几种方式来加载配置:
1、properties文件;
2、YAML文件;
3、系统环境变量;
4、命令行参数
配置属性加载的顺序如下:
1、开发者工具 `Devtools` 全局配置参数;
2、单元测试上的 `@TestPropertySource` 注解指定的参数;
3、单元测试上的 `@SpringBootTest` 注解指定的参数;
4、命令行指定的参数,如 `java -jar springboot.jar --name="Java技术栈"`;
5、命令行中的 `SPRING_APPLICATION_JSONJSON` 指定参数, 如 `java -Dspring.application.json='{"name":"Java技术栈"}' -jar springboot.jar`
6、`ServletConfig` 初始化参数;
7、`ServletContext` 初始化参数;
8、JNDI参数(如 `java:comp/env/spring.application.json`);
9、Java系统参数(来源:`System.getProperties()`);
10、操作系统环境变量参数;
11、`RandomValuePropertySource` 随机数,仅匹配:`ramdom.*`;
12、JAR包外面的配置文件参数(`application-{profile}.properties(YAML)`)
13、JAR包里面的配置文件参数(`application-{profile}.properties(YAML)`)
14、JAR包外面的配置文件参数(`application.properties(YAML)`)
15、JAR包里面的配置文件参数(`application.properties(YAML)`)
16、`@Configuration`配置文件上 `@PropertySource` 注解加载的参数;
17、默认参数(通过 `SpringApplication.setDefaultProperties` 指定);
18、Spring Boot 可以兼容老 Spring 项目吗,如何做?
可以兼容,使用 @ImportResource 注解导入老 Spring 项目配置文件。
1.在生产中使用HTTPS
2.使用Snyk检查你的依赖关系
3.升级到最新版本
4.启用CSRF保护
5.使用内容安全策略防止XSS攻击
6.使用OpenID Connect进行身份验证
7.管理密码?使用密码哈希!
8.安全地存储秘密
9.使用OWASP的ZAP测试您的应用程序
10.让你的安全团队进行代码审查
20、Spring Boot 2.X 有什么新特性?与 1.X 有什么区别?
配置变更
JDK 版本升级
第三方类库升级
响应式 Spring 编程支持
HTTP/2 支持
配置属性绑定
21、JavaBean是什么时候创建的?
@Controller
public class TestController {
public TestController(){
System.out.println("TestController 创建了");
}
}
该方法就是Spring Boot项目启动时 所要执行的代码,根据阅读可以分为以下步骤
加载环境变量
创建上下文 ConfigurableApplicationContext 对象
准备上下文 prepareContext()
刷新上下文 refreshContext()
刷新之后的处理 afterRefresh()
22、SpringBoot框架中,JavaBean都是单例的吗?多例怎么设置?
spring bean作用域有以下5个:
singleton: 单例模式,当spring创建applicationContext容器的时候,spring会欲初始化所有的该作用域实例,加上lazy-init就可以避免预处理;
prototype: 原型模式,每次通过getBean获取该bean就会新产生一个实例,创建后spring将不再对其管理;
下面是在web项目下才用到的
request: 搞web的大家都应该明白request的域了吧,就是每次请求都新产生一个实例,和prototype不同就是创建后,接下来的管理,spring依然在监听;
session: 每次会话,同上;
global session: 全局的web域,类似于servlet中的application。
好了,上面都说了spring的controller默认是单例,那很自然就是singleton了。
为什么spring要默认是单例呢?原因有二:
1、为了性能:这个不用废话了,单例不用每次都new,当然快了。
2、不需要多例:不需要多例会让很多人迷惑,因为spring mvc官方也没明确说不可以多例。
我这里说不需要的原因是看开发者怎么用了,如果你给controller中定义很多的属性,那么单例肯定会出现竞争访问了。
因此,只要controller中不定义属性,那么单例完全是安全的。下面给个例子说明下
从此可见,单例是不安全的,会导致属性重复使用。
最佳实践:
1、不要在controller中定义成员变量。
2、万一必须要定义一个非静态成员变量时候,则通过注解@Scope(“prototype”),将其设置为多例模式。
23、Spring Boot、Spring MVC 和 Spring 有什么区别?
SpringFrame
SpringBoot
Spring 和 SpringMVC 的问题在于需要配置大量的参数
@Controller
public class viewController {
private int index = 0;//非静态
@RequestMapping("/show")
public String toShow(ModelMap model) {
System.out.println(++i);
return"show";
}
Spring Boot 通过一个自动配置和启动的项来目解决这个问题。为了更快的构建产品就绪应用程序,Spring Boot 提供了一些非功能性特征。
24、什么是自动配置?
Spring 和 SpringMVC 的问题在于需要配置大量的参数
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
25、什么是 Spring Boot Stater ?
启动器是一套方便的依赖没描述符,它可以放在自己的程序中。你可以一站式的获取你所需要的 Spring 和相关技术,而不需要依赖描述符的通过示例代码搜索和复制黏贴的负载。
例如,如果你想使用 Sping 和 JPA 访问数据库,只需要你的项目包含 spring-boot-starter-data-jpa 依赖项,你就可以完美进行
26、你能否举一个例子来解释更多 Staters 的内容?
让我们来思考一个 Stater 的例子 -Spring Boot Stater Web。
如果你想开发一个 web 应用程序或者是公开 REST 服务的应用程序。Spring Boot Start Web 是首选。让我们使用 Spring Initializr 创建一个 Spring Boot Start Web 的快速项目。
Spring Boot Start Web 的依赖项
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
27、Spring Boot 还提供了其它的哪些 Starter Project Options?
Spring Boot 也提供了其它的启动器项目包括,包括用于开发特定类型应用程序的典型依赖项。
spring-boot-starter-web-services - SOAP Web Services
spring-boot-starter-web - Web 和 RESTful 应用程序
spring-boot-starter-test - 单元测试和集成测试
spring-boot-starter-jdbc - 传统的 JDBC
spring-boot-starter-hateoas - 为服务添加 HATEOAS 功能
spring-boot-starter-security - 使用 SpringSecurity 进行身份验证和授权
spring-boot-starter-data-jpa - 带有 Hibeernate 的 Spring Data JPA
spring-boot-starter-data-rest - 使用 Spring Data REST 公布简单的 REST 服务
28、Spring 是如何快速创建产品就绪应用程序的?
Spring Boot 致力于快速产品就绪应用程序。为此,它提供了一些譬如高速缓存,日志记录,监控和嵌入式服务器等开箱即用的非功能性特征。
spring-boot-starter-actuator(使用一些如监控和跟踪应用的高级功能)
spring-boot-starter-undertow, spring-boot-starter-jetty,spring-boot-starter-tomcat (选择您的特定嵌入式 Servlet 容器)
spring-boot-starter-logging(使用 logback 进行日志记录)
spring-boot-starter-cache (启用 Spring Framework 的缓存支持)
Spring2 和 Spring5 所需要的最低 Java 版本是什么?
Spring Boot 2.0 需要 Java8 或者更新的版本。Java6 和 Java7 已经不再支持。
推荐阅读:
Spring Boot 2.0.0 M1 Release Notes
29、创建一个 Spring Boot Project 的最简单的方法是什么?
Spring Initializr是启动 Spring Boot Projects 的一个很好的工具。
就像上图中所展示的一样,我们需要做一下几步:
登录 Spring Initializr,按照以下方式进行选择:
选择 com.in28minutes.springboot 为组
选择 studet-services 为组件
选择下面的依赖项
Web
Actuator
DevTools
点击生 GenerateProject
将项目导入 Eclipse。文件 - 导入 - 现有的 Maven 项目
32、如何使用 SpringBoot 自动重装我的应用程序?
使用 Spring Boot 开发工具。
把 Spring Boot 开发工具添加进入你的项目是简单的。
把下面的依赖项添加至你的 Spring Boot Project pom.xml 中
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope></dependency>
重启应用程序,然后就可以了
33、我们能否在 spring-boot-starter-web 中用 jetty 代替 tomcat?
在 spring-boot-starter-web 移除现有的依赖项,并把下面这些添加进去。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jetty</artifactId></dependency>
34、如何使用 Spring Boot 部署到不同的服务器?
你需要做下面两个步骤:
在一个项目中生成一个 war 文件。
将它部署到你最喜欢的服务器(websphere 或者 Weblogic 或者 Tomcat and so on)
35、RequestMapping 和 GetMapping 的不同之处在哪里?
RequestMapping 具有类属性的,可以进行 GET,POST,PUT 或者其它的注释中具有的请求方法。
GetMapping 是 GET 请求方法中的一个特例。它只是 ResquestMapping 的一个延伸,目的是为了提高清晰度。
36、JPA 和 Hibernate 有哪些区别?
JPA 是一个规范或者接口
Hibernate 是 JPA 的一个实现
当我们使用 JPA 的时候,我们使用 javax.persistence 包中的注释和接口时,不需要使用 hibernate 的导入包。
我们建议使用 JPA 注释,因为哦我们没有将其绑定到 Hibernate 作为实现。后来(我知道 - 小于百分之一的几率),我们可以使用另一种 JPA 实现。
37、使用 Spring Boot 启动连接到内存数据库 H2 的 JPA 应用程序需要哪些依赖项?
在 Spring Boot 项目中,当你确保下面的依赖项都在类路里面的时候,你可以加载 H2 控制台。
web 启动器
h2
jpa 数据启动器
38、如何不通过任何配置来选择 Hibernate 作为 JPA 的默认实现?
因为 Spring Boot 是自动配置的。
下面是我们添加的依赖项
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>
spring-boot-stater-data-jpa 对于 Hibernate 和 JPA 有过渡依赖性。
当 Spring Boot 在类路径中检测到 Hibernate 中,将会自动配置它为默认的 JPA 实现。