Skip to content

Commit 9733291

Browse files
committed
Update springboot-questions.md
1 parent c072cda commit 9733291

File tree

1 file changed

+93
-3
lines changed

1 file changed

+93
-3
lines changed

docs/system-design/framework/spring/springboot-questions.md

+93-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22

3-
> 本文由JavaGuide整理翻译自(做了适当删减和修改):
3+
> 本文由JavaGuide整理翻译自(做了适当删减、修改和补充):
44
>
55
> - https://www.javaguides.net/2018/11/spring-boot-interview-questions-and-answers.html
66
> - https://www.algrim.co/posts/101-spring-boot-interview-questions
@@ -37,7 +37,7 @@ Spring Boot Starters 是一系列依赖关系的集合,因为它的存在,
3737
</dependency>
3838
```
3939

40-
### 如何在Spring Boot应用程序中使用Jetty而不是Tomcat?
40+
### 5.如何在Spring Boot应用程序中使用Jetty而不是Tomcat?
4141

4242
Spring Boot Web starter使用Tomcat作为默认的嵌入式servlet容器, 如果你想使用 Jetty 的话只需要修改pom.xml(Maven)或者build.gradle(Gradle)就可以了。
4343

@@ -73,7 +73,7 @@ compile("org.springframework.boot:spring-boot-starter-jetty")
7373

7474
说个题外话,从上面可以看出使用 Gradle 更加简洁明了,但是国内目前还是 Maven 使用的多一点,我个人觉得 Gradle 在很多方面都要好很多。
7575

76-
### 介绍一下@SpringBootApplication注解
76+
### 6.介绍一下@SpringBootApplication注解
7777

7878
```java
7979
package org.springframework.boot.autoconfigure;
@@ -108,3 +108,93 @@ public @interface SpringBootConfiguration {
108108
- `@ComponentScan`: 扫描被`@Component` (`@Service`,`@Controller`)注解的bean,注解默认会扫描该类所在的包下所有的类。
109109
- `@Configuration`:允许在上下文中注册额外的bean或导入其他配置类
110110

111+
### (重要)Spring Boot 的自动配置是如何实现的?
112+
113+
这个是因为`@SpringBootApplication `注解的原因,在上一个问题中已经提到了这个注解。我们知道 `@SpringBootApplication `看作是 `@Configuration``@EnableAutoConfiguration``@ComponentScan ` 注解的集合。
114+
115+
- `@EnableAutoConfiguration`:启用 SpringBoot 的自动配置机制
116+
- `@ComponentScan`: 扫描被`@Component` (`@Service`,`@Controller`)注解的bean,注解默认会扫描该类所在的包下所有的类。
117+
- `@Configuration`:允许在上下文中注册额外的bean或导入其他配置类
118+
119+
`@EnableAutoConfiguration`是启动自动配置的关键,源码如下(建议自己打断点调试,走一遍基本的流程):
120+
121+
```java
122+
import java.lang.annotation.Documented;
123+
import java.lang.annotation.ElementType;
124+
import java.lang.annotation.Inherited;
125+
import java.lang.annotation.Retention;
126+
import java.lang.annotation.RetentionPolicy;
127+
import java.lang.annotation.Target;
128+
import org.springframework.context.annotation.Import;
129+
130+
@Target({ElementType.TYPE})
131+
@Retention(RetentionPolicy.RUNTIME)
132+
@Documented
133+
@Inherited
134+
@AutoConfigurationPackage
135+
@Import({AutoConfigurationImportSelector.class})
136+
public @interface EnableAutoConfiguration {
137+
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
138+
139+
Class<?>[] exclude() default {};
140+
141+
String[] excludeName() default {};
142+
}
143+
```
144+
145+
`@EnableAutoConfiguration` 注解通过Spring 提供的 `@Import` 注解导入了`AutoConfigurationImportSelector`类(`@Import` 注解可以导入配置类或者Bean到当前类中)。
146+
147+
` ``AutoConfigurationImportSelector`类中`getCandidateConfigurations`方法会将所有自动配置类的信息以 List 的形式返回。这些配置信息会被 Spring 容器作 bean 来管理。
148+
149+
```java
150+
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
151+
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
152+
getBeanClassLoader());
153+
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
154+
+ "are using a custom packaging, make sure that file is correct.");
155+
return configurations;
156+
}
157+
```
158+
159+
自动配置信息有了,那么自动配置还差什么呢?
160+
161+
`@Conditional` 注解。`@ConditionalOnClass`(指定的类必须存在于类路径下),`@ConditionalOnBean`(容器中是否有指定的Bean)等等都是对`@Conditional`注解的扩展。拿 Spring Security 的自动配置举个例子:
162+
163+
`SecurityAutoConfiguration`中导入了`WebSecurityEnablerConfiguration`类,`WebSecurityEnablerConfiguration`源代码如下:
164+
165+
```java
166+
@Configuration
167+
@ConditionalOnBean(WebSecurityConfigurerAdapter.class)
168+
@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
169+
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
170+
@EnableWebSecurity
171+
public class WebSecurityEnablerConfiguration {
172+
173+
}
174+
```
175+
176+
`WebSecurityEnablerConfiguration`类中使用`@ConditionalOnBean`指定了容器中必须还有`WebSecurityConfigurerAdapter` 类或其实现类。所以,一般情况下 Spring Security 配置类都会去实现 `WebSecurityConfigurerAdapter`,这样自动将配置就完成了。
177+
178+
更多内容可以参考这篇文章:https://sylvanassun.github.io/2018/01/08/2018-01-08-spring_boot_auto_configure/
179+
180+
### 7. Spring Boot支持哪些嵌入式web容器?
181+
182+
Spring Boot支持以下嵌入式servlet容器:
183+
184+
| **Name** | **Servlet Version** |
185+
| ------------ | ------------------- |
186+
| Tomcat 9.0 | 4.0 |
187+
| Jetty 9.4 | 3.1 |
188+
| Undertow 2.0 | 4.0 |
189+
190+
您还可以将Spring引导应用程序部署到任何Servlet 3.1+兼容的 Web 容器中。
191+
192+
这就是你为什么可以通过直接像运行 普通 Java 项目一样运行 SpringBoot 项目。这样的确省事了很多,方便了我们进行开发,降低了学习难度。
193+
194+
### 什么是Spring Security ?
195+
196+
Spring Security 应该属于 Spring 全家桶中学习曲线比较陡峭的几个模块之一,下面我将从起源和定义这两个方面来简单介绍一下它。
197+
198+
- **起源:** Spring Security 实际上起源于 Acegi Security,这个框架能为基于 Spring 的企业应用提供强大而灵活安全访问控制解决方案,并且框架这个充分利用 Spring 的 IoC 和 AOP 功能,提供声明式安全访问控制的功能。后面,随着这个项目发展, Acegi Security 成为了Spring官方子项目,后来被命名为 “Spring Security”。
199+
- **定义:**Spring Security 是一个功能强大且高度可以定制的框架,侧重于为Java 应用程序提供身份验证和授权。——[官方介绍](https://spring.io/projects/spring-security)
200+

0 commit comments

Comments
 (0)