|
1 | 1 |
|
2 | 2 |
|
3 |
| -> 本文由JavaGuide整理翻译自(做了适当删减和修改): |
| 3 | +> 本文由JavaGuide整理翻译自(做了适当删减、修改和补充): |
4 | 4 | >
|
5 | 5 | > - https://www.javaguides.net/2018/11/spring-boot-interview-questions-and-answers.html
|
6 | 6 | > - https://www.algrim.co/posts/101-spring-boot-interview-questions
|
@@ -37,7 +37,7 @@ Spring Boot Starters 是一系列依赖关系的集合,因为它的存在,
|
37 | 37 | </dependency>
|
38 | 38 | ```
|
39 | 39 |
|
40 |
| -### 如何在Spring Boot应用程序中使用Jetty而不是Tomcat? |
| 40 | +### 5.如何在Spring Boot应用程序中使用Jetty而不是Tomcat? |
41 | 41 |
|
42 | 42 | Spring Boot Web starter使用Tomcat作为默认的嵌入式servlet容器, 如果你想使用 Jetty 的话只需要修改pom.xml(Maven)或者build.gradle(Gradle)就可以了。
|
43 | 43 |
|
@@ -73,7 +73,7 @@ compile("org.springframework.boot:spring-boot-starter-jetty")
|
73 | 73 |
|
74 | 74 | 说个题外话,从上面可以看出使用 Gradle 更加简洁明了,但是国内目前还是 Maven 使用的多一点,我个人觉得 Gradle 在很多方面都要好很多。
|
75 | 75 |
|
76 |
| -### 介绍一下@SpringBootApplication注解 |
| 76 | +### 6.介绍一下@SpringBootApplication注解 |
77 | 77 |
|
78 | 78 | ```java
|
79 | 79 | package org.springframework.boot.autoconfigure;
|
@@ -108,3 +108,93 @@ public @interface SpringBootConfiguration {
|
108 | 108 | - `@ComponentScan`: 扫描被`@Component` (`@Service`,`@Controller`)注解的bean,注解默认会扫描该类所在的包下所有的类。
|
109 | 109 | - `@Configuration`:允许在上下文中注册额外的bean或导入其他配置类
|
110 | 110 |
|
| 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