Skip to content

Commit b341830

Browse files
committed
几道简单的 SpringBoot面试题
1 parent 013be64 commit b341830

File tree

2 files changed

+199
-2
lines changed

2 files changed

+199
-2
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
1. **[开发 RestFul Web 服务](./docs/basis/sringboot-restful-web-service.md)**
2727
2. **[RestController VS Controller](./docs/basis/RestControllerVSController.md)**
2828
3. **[Spring Boot 异常处理](./docs/advanced/springboot-handle-exception.md)**
29-
4. **[实际项目中我们是这样做异常处理的](./docs/advanced/springboot-handle-exception-plus.md)**
29+
4. **[实际项目中我们是这样做异常处理的](./docs/advanced/springboot-handle-exception-plus)**
3030
5. [使用 spring-boot-devtools 进行热部署](./docs/basis/spring-boot-devtools.md)
3131
6. **[ Spring Boot JPA 基础:常见操作解析](./docs/basis/springboot-jpa.md)**
3232
7. **[JPA 中非常重要的连表查询就是这么简单](./docs/basis/springboot-jpa-lianbiao.md)**
@@ -47,7 +47,7 @@
4747

4848
### 面试题
4949

50-
代办...
50+
- [几道简单的 SpringBoot面试题](./docs/interview/springboot-questions.md)
5151

5252
## 说明
5353

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
> 本文由JavaGuide整理翻译自(做了适当删减、修改和补充):
2+
>
3+
> - https://www.javaguides.net/2018/11/spring-boot-interview-questions-and-answers.html
4+
> - https://www.algrim.co/posts/101-spring-boot-interview-questions
5+
6+
### 1. 什么是 Spring Boot?
7+
8+
首先,重要的是要理解 Spring Boot 并不是一个框架,它是一种创建独立应用程序的更简单方法,只需要很少或没有配置(相比于 Spring 来说)。Spring Boot最好的特性之一是它利用现有的 Spring 项目和第三方项目来开发适合生产的应用程序。
9+
10+
### 2. 说出使用Spring Boot的主要优点
11+
12+
1. 开发基于 Spring 的应用程序很容易。
13+
2. Spring Boot 项目所需的开发或工程时间明显减少,通常会提高整体生产力。
14+
3. Spring Boot不需要编写大量样板代码、XML配置和注释。
15+
4. Spring引导应用程序可以很容易地与Spring生态系统集成,如Spring JDBC、Spring ORM、Spring Data、Spring Security等。
16+
5. Spring Boot遵循“固执己见的默认配置”,以减少开发工作(默认配置可以修改)。
17+
6. Spring Boot 应用程序提供嵌入式HTTP服务器,如Tomcat和Jetty,可以轻松地开发和测试web应用程序。(这点很赞!普通运行Java程序的方式就能运行基于Spring Boot web 项目,省事很多)
18+
7. Spring Boot提供命令行接口(CLI)工具,用于开发和测试Spring Boot应用程序,如Java或Groovy。
19+
8. Spring Boot提供了多种插件,可以使用内置工具(如Maven和Gradle)开发和测试Spring Boot应用程序。
20+
21+
### 3. 为什么需要Spring Boot?
22+
23+
Spring Framework旨在简化J2EE企业应用程序开发。Spring Boot Framework旨在简化Spring开发。
24+
25+
![why-we-need-springboot](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-7/why-we-need-springboot.png)
26+
27+
### 4. 什么是 Spring Boot Starters?
28+
29+
Spring Boot Starters 是一系列依赖关系的集合,因为它的存在,项目的依赖之间的关系对我们来说变的更加简单了。举个例子:在没有Spring Boot Starters之前,我们开发REST服务或Web应用程序时; 我们需要使用像Spring MVC,Tomcat和Jackson这样的库,这些依赖我们需要手动一个一个添加。但是,有了 Spring Boot Starters 我们只需要一个只需添加一个**spring-boot-starter-web**一个依赖就可以了,这个依赖包含的字依赖中包含了我们开发REST 服务需要的所有依赖。
30+
31+
```xml
32+
<dependency>
33+
<groupId>org.springframework.boot</groupId>
34+
<artifactId>spring-boot-starter-web</artifactId>
35+
</dependency>
36+
```
37+
38+
### 5. 如何在Spring Boot应用程序中使用Jetty而不是Tomcat?
39+
40+
Spring Boot Web starter使用Tomcat作为默认的嵌入式servlet容器, 如果你想使用 Jetty 的话只需要修改pom.xml(Maven)或者build.gradle(Gradle)就可以了。
41+
42+
**Maven:**
43+
44+
```xml
45+
<!--从Web启动器依赖中排除Tomcat-->
46+
<dependency>
47+
<groupId>org.springframework.boot</groupId>
48+
<artifactId>spring-boot-starter-web</artifactId>
49+
<exclusions>
50+
<exclusion>
51+
<groupId>org.springframework.boot</groupId>
52+
<artifactId>spring-boot-starter-tomcat</artifactId>
53+
</exclusion>
54+
</exclusions>
55+
</dependency>
56+
<!--添加Jetty依赖-->
57+
<dependency>
58+
<groupId>org.springframework.boot</groupId>
59+
<artifactId>spring-boot-starter-jetty</artifactId>
60+
</dependency>
61+
```
62+
63+
**Gradle:**
64+
65+
```groovy
66+
compile("org.springframework.boot:spring-boot-starter-web") {
67+
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
68+
}
69+
compile("org.springframework.boot:spring-boot-starter-jetty")
70+
```
71+
72+
说个题外话,从上面可以看出使用 Gradle 更加简洁明了,但是国内目前还是 Maven 使用的多一点,我个人觉得 Gradle 在很多方面都要好很多。
73+
74+
### 6. 介绍一下@SpringBootApplication注解
75+
76+
```java
77+
package org.springframework.boot.autoconfigure;
78+
@Target(ElementType.TYPE)
79+
@Retention(RetentionPolicy.RUNTIME)
80+
@Documented
81+
@Inherited
82+
@SpringBootConfiguration
83+
@EnableAutoConfiguration
84+
@ComponentScan(excludeFilters = {
85+
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
86+
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
87+
public @interface SpringBootApplication {
88+
......
89+
}
90+
```
91+
92+
```java
93+
package org.springframework.boot;
94+
@Target(ElementType.TYPE)
95+
@Retention(RetentionPolicy.RUNTIME)
96+
@Documented
97+
@Configuration
98+
public @interface SpringBootConfiguration {
99+
100+
}
101+
```
102+
103+
可以看出大概可以把 `@SpringBootApplication `看作是 `@Configuration``@EnableAutoConfiguration``@ComponentScan ` 注解的集合。根据 SpringBoot官网,这三个注解的作用分别是:
104+
105+
- `@EnableAutoConfiguration`:启用 SpringBoot 的自动配置机制
106+
- `@ComponentScan`: 扫描被`@Component` (`@Service`,`@Controller`)注解的bean,注解默认会扫描该类所在的包下所有的类。
107+
- `@Configuration`:允许在上下文中注册额外的bean或导入其他配置类
108+
109+
### 7. (重要)Spring Boot 的自动配置是如何实现的?
110+
111+
这个是因为`@SpringBootApplication `注解的原因,在上一个问题中已经提到了这个注解。我们知道 `@SpringBootApplication `看作是 `@Configuration``@EnableAutoConfiguration``@ComponentScan ` 注解的集合。
112+
113+
- `@EnableAutoConfiguration`:启用 SpringBoot 的自动配置机制
114+
- `@ComponentScan`: 扫描被`@Component` (`@Service`,`@Controller`)注解的bean,注解默认会扫描该类所在的包下所有的类。
115+
- `@Configuration`:允许在上下文中注册额外的bean或导入其他配置类
116+
117+
`@EnableAutoConfiguration`是启动自动配置的关键,源码如下(建议自己打断点调试,走一遍基本的流程):
118+
119+
```java
120+
import java.lang.annotation.Documented;
121+
import java.lang.annotation.ElementType;
122+
import java.lang.annotation.Inherited;
123+
import java.lang.annotation.Retention;
124+
import java.lang.annotation.RetentionPolicy;
125+
import java.lang.annotation.Target;
126+
import org.springframework.context.annotation.Import;
127+
128+
@Target({ElementType.TYPE})
129+
@Retention(RetentionPolicy.RUNTIME)
130+
@Documented
131+
@Inherited
132+
@AutoConfigurationPackage
133+
@Import({AutoConfigurationImportSelector.class})
134+
public @interface EnableAutoConfiguration {
135+
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
136+
137+
Class<?>[] exclude() default {};
138+
139+
String[] excludeName() default {};
140+
}
141+
```
142+
143+
`@EnableAutoConfiguration` 注解通过Spring 提供的 `@Import` 注解导入了`AutoConfigurationImportSelector`类(`@Import` 注解可以导入配置类或者Bean到当前类中)。
144+
145+
` ``AutoConfigurationImportSelector`类中`getCandidateConfigurations`方法会将所有自动配置类的信息以 List 的形式返回。这些配置信息会被 Spring 容器作 bean 来管理。
146+
147+
```java
148+
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
149+
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
150+
getBeanClassLoader());
151+
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
152+
+ "are using a custom packaging, make sure that file is correct.");
153+
return configurations;
154+
}
155+
```
156+
157+
自动配置信息有了,那么自动配置还差什么呢?
158+
159+
`@Conditional` 注解。`@ConditionalOnClass`(指定的类必须存在于类路径下),`@ConditionalOnBean`(容器中是否有指定的Bean)等等都是对`@Conditional`注解的扩展。拿 Spring Security 的自动配置举个例子:
160+
161+
`SecurityAutoConfiguration`中导入了`WebSecurityEnablerConfiguration`类,`WebSecurityEnablerConfiguration`源代码如下:
162+
163+
```java
164+
@Configuration
165+
@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
166+
@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
167+
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
168+
@EnableWebSecurity
169+
public class WebSecurityEnablerConfiguration {
170+
171+
}
172+
```
173+
174+
`WebSecurityEnablerConfiguration`类中使用`@ConditionalOnBean`指定了容器中必须还有`WebSecurityConfigurerAdapter` 类或其实现类。所以,一般情况下 Spring Security 配置类都会去实现 `WebSecurityConfigurerAdapter`,这样自动将配置就完成了。
175+
176+
更多内容可以参考这篇文章:https://sylvanassun.github.io/2018/01/08/2018-01-08-spring_boot_auto_configure/
177+
178+
### 8. Spring Boot支持哪些嵌入式web容器?
179+
180+
Spring Boot支持以下嵌入式servlet容器:
181+
182+
| **Name** | **Servlet Version** |
183+
| ------------ | ------------------- |
184+
| Tomcat 9.0 | 4.0 |
185+
| Jetty 9.4 | 3.1 |
186+
| Undertow 2.0 | 4.0 |
187+
188+
您还可以将Spring引导应用程序部署到任何Servlet 3.1+兼容的 Web 容器中。
189+
190+
这就是你为什么可以通过直接像运行 普通 Java 项目一样运行 SpringBoot 项目。这样的确省事了很多,方便了我们进行开发,降低了学习难度。
191+
192+
### 9. 什么是Spring Security ?
193+
194+
Spring Security 应该属于 Spring 全家桶中学习曲线比较陡峭的几个模块之一,下面我将从起源和定义这两个方面来简单介绍一下它。
195+
196+
- **起源:** Spring Security 实际上起源于 Acegi Security,这个框架能为基于 Spring 的企业应用提供强大而灵活安全访问控制解决方案,并且框架这个充分利用 Spring 的 IoC 和 AOP 功能,提供声明式安全访问控制的功能。后面,随着这个项目发展, Acegi Security 成为了Spring官方子项目,后来被命名为 “Spring Security”。
197+
- **定义:**Spring Security 是一个功能强大且高度可以定制的框架,侧重于为Java 应用程序提供身份验证和授权。——[官方介绍](https://spring.io/projects/spring-security)

0 commit comments

Comments
 (0)