Spring Boot -总结

Spring Boot -总结

:以下Spring Boot源码,如果没有特殊说明都是基于【Spring Boot 2.4.5】版本进行列举。


如想了解更多更全面的Java必备内容可以阅读:所有JAVA必备知识点面试题文章目录:



1、SpringBoot、Spring MVC和Spring有什么区别?
  • Spring:Spring最重要的特征是依赖注入。所有Spring Modules不是依赖注入就是IOC控制反转。当我们恰当的使用DI或者是IOC的时候,可以开发松耦合应用。
  • Spring MVC:Spring MVC提供了一种分离式的方法来开发Web应用。通过运用像DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。
  • SpringBoot:Spring和Spring MVC的问题在于需要配置大量的参数。SpringBoot通过一个自动配置和启动的项来解决这个问题。
2、SpringBoot有哪些优点?
  • 简化配置:启动器自动依赖其他组件,简少了 maven 的配置,避免大量的Maven导入和各种版本冲突。
  • 独立运行:内嵌了各种 servlet 容器,Tomcat、Jetty 等,现在不再需要打成war 包部署到容器中。
  • 自动配置:根据当前类路径下的类、jar 包来自动配置 bean。
  • 应用监控:提供一系列端点可以监控服务及应用,做健康检测。
3、SpringBoot核心配置文件bootstrap.properties和application.properties 有何区别 ?
  • bootstrap(.yml 或者 .properties):boostrap 由父 ApplicationContext 加载的,比applicaton优先加载,配置在应用程序上下文的引导阶段生效。一般来说我们在 SpringCloud Config 或者Nacos中会用到它。且boostrap里面的属性不能被覆盖;
  • application (.yml或者.properties):由ApplicatonContext 加载,用于 SpringBoot项目的自动化配置。
4、SpringBoot的核心注解是什么?

@SpringBootApplication是 SpringBoot 的核心注解。
@SpringBootApplication是一个复合注解。他提供了别名定制的属性@EnableAutoConfiguration和@ComponentScan。
单个@SpringBootApplication注解可用于启用这三个功能,即:

  • @SpringBootConfiguration ----> @Configuration:组合了 @Configuration 注解,实现配置文件的功能。
  • @EnableAutoConfiguration:启用Spring Boot的自动配置机制。
  • @ComponentScan:@Component在应用程序所在的软件包上启用扫描。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
	···
}
3、什么是JavaConfig?

JavaConfig:配置Spring IOC容器的纯Java方法。因此它有助于避免使用XML配置。

优点:

  • 面向对象的配置:由于配置被定义为JavaConfig中的类,因此用户可以充分使用Java中的面向对象功能。一个配置类可以继承另一个,重写它的@Bean方法等。
  • 减少或者消除XML配置:提供了一种纯Java的方法来配置与XML配置概念相似的Spring容器。
4、请说说【@Configuration】注解的作用?

在启动类里面标注了 @Configuration,意味着它其实也是一个 IoC容器的配置类
spring3 开始,spring 就支持了两种 bean 的配置方式,一种是基于 xml 文件方式、另一种就是 JavaConfig任何一个标注了@Configuration 的 Java 类定义都是一个JavaConfig 配置类。而在这个配置类中,任何标注了@Bean 的方法,它的返回值都会作为 Bean 定义注册到Spring 的 IOC 容器,方法名默认成为这个bean的id。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
	···
}
5、请说说【@EnableAutoConfiguration】注解的实现原理?

EnableAutoConfiguration:是帮助Spring Boot应用把所有符合条件的配置类都加载到当前的IoC容器中。
借助了Spring 框架提供的一个工具类 SpringFactoriesLoader 的支持。以及用到了 Spring 提供的条件注解@Conditional,选择性的针对需要加载的bean进行条件过滤。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage//@Import({Registrar.class})
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
	···
}
5、请说说【@Import】注解的作用?

import :只能用在类上,将bean注入到IOC容器中。
@Import 注解可以配置三种不同的类,即:

  1. 基于普通bean或者带有@Configuration的bean进行注入。

  2. 实现 ImportSelector 接口进行动态注入,接口会重写一个selectImports方法。

    @Import({AutoConfigurationImportSelector.class})
    public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {···}
    public interface DeferredImportSelector extends ImportSelector {···}
    
  3. 实现 ImportBeanDefinitionRegistrar 接口进行动态注入。

    @Import({Registrar.class})
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {···{}
    
6、请说说AutoConfigurationImportSelector实现原理?

首先重写了selectImports接口,具体的实现是:

  1. 查看是否开启自动装配
  2. 获取注解配置的元素信息
  3. 获取配置EnableAutoConfiguration作为key的所有自动配置类,在META-INF/spring.factories文件中,通过SpringFactoriesLoader加载器
  4. 删除配置重复的类信息
  5. 排除注解中的exclude和excludeName属性指定的类,以及application.properties文件中指定的spring.autoconfigure.exclude属性值指定的类都需要排除
  6. 检查排除类名集合的合法性,如果是排除的类,但是在spring.factories文件没有出现,则抛出异常
  7. 过滤条件(condition)中自动装配组件
  8. 触发自动装配事件
  9. 将需要自动配置的实体信息转换成数组返回。
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		if (!this.isEnabled(annotationMetadata)) {//查看是否开启自动装配
			return NO_IMPORTS;
		} else {
			//获得需要自动配置的实体信息
			AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
			返回需要自动配置的实体集
			return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
		}
	}
	//获得需要自动配置的实体信息
	protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
		if (!this.isEnabled(annotationMetadata)) {//查看是否开启自动装配
			return EMPTY_ENTRY;
		} else {
			//获取注解配置的元素信息
			AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
			//获取配置EnableAutoConfiguration作为key的所有自动配置类,在META-INF/spring.factories文件中,通过SpringFactoriesLoader加载器
			List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
			//删除配置重复的类信息
			configurations = this.removeDuplicates(configurations);
			//排除注解中的exclude和excludeName属性指定的类,以及application.properties文件中指定的spring.autoconfigure.exclude属性值指定的类都需要排除,exclusions需要排除的配置类信息集合
			Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
			//检查排除类名集合的合法性,如果是排除的类,但是在spring.factories文件没有出现,则抛出异常。
			this.checkExcludedClasses(configurations, exclusions);
			//将exclusions中的信息从configurations中移除
			configurations.removeAll(exclusions);
			//过滤条件(condition)中自动装配组件
			configurations = this.getConfigurationClassFilter().filter(configurations);
			//触发自动装配事件
			this.fireAutoConfigurationImportEvents(configurations, exclusions);
			return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
		}
	}

	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
		return configurations;
	}
···	
}
7、为什么要对configurations进行过滤呢?

原因是很多的@Configuration其实是依托于其他的框架来加载的。
如果当前的classpath环境下没有相关联的依赖,则意味着这些类没必要进行加载,所以,通过这种条件过滤可以有效的减少@configuration类的数量从而降低SpringBoot的启动时间。

7、Conditional中的常用注解有哪些?
Conditions描述
@ConditionalOnBean在存在某个 bean 的时候
@ConditionalOnMissingBean不存在某个 bean 的时候
@ConditionalOnClass当前 classpath 可以找到某个类型的类时
@ConditionalOnMissingClass当前 classpath 不可以找到某个类型的类时
@ConditionalOnResource当前 classpath 是否存在某个资源文件
@ConditionalOnProperty当前 jvm 是否包含某个系统属性为某个值
@ConditionalOnWebApplication当前 spring context 是否是 web 应用程序
8、请说说【@ComponentScan】注解的作用?

ComponentScan:会扫描标有该注解类所在的包下的所有加了相关注解标识(@Component 、@Repository、@Service、@Controller)的类,自动装配到 spring 的 Ioc 容器中。相当于 xml 配置文件中的< context:component-scan>。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
	···
}
9、什么是 Starter?

首先它提供了一个自动化配置类,一般命名为 XXXAutoConfiguration ,在这个配置类中通过条件注解来决定一个配置是否生效(条件注解就是 Spring 中原本就有的),然后它还会提供一系列的默认配置,也允许开发者根据实际情况自定义相关配置,然后通过类型安全的属性注入将这些配置属性注入进来,新注入的属性会代替掉默认属性。正因为如此,很多第三方框架,我们只需要引入依赖就可以直接使用了。即:开箱即用。

工作原理:Spring Boot 在启动时扫描项目所依赖的JAR包,寻找包含spring.factories文件的JAR包,根据spring.factories配置加载AutoConfigure类,根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context。

10、Spring Boot 有哪几种读取配置的方式?
  • @Value注解:加载单个属性值
  • @ConfigurationProperties注解:可以加载一组属性的值,针对于要加载的属性过多的情况,比@Value注解更加简洁。
11、@value和@configurationproperties注解的区别?
@ConfigurationProperties@value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303数据校验 支持不支持
复杂类型封装支持不支持
12、运行 Spring Boot 有哪几种方式?
  • 用命令打包或者放到容器中运行
  • 用 Maven 插件运行
  • 直接执行 main 方法运行
13、SpringBoot中如何解决跨域问题 ?

项目中前后端分离部署,所以需要解决跨域的问题。
跨域可以在前端通过JSONP来解决,但是JSONP只可以发送 GET 请求,无法发送其他类型的请求,在 RESTful 风格的应用中,就显得非常鸡肋
因此我们推荐在后端通过 (CORS,Cross-origin resource sharing) 来解决跨域问题。这种解决方案并非 Spring Boot 特有的,在传统的 SSM 框架中,就可以通过 CORS 来解决跨域问题,只不过之前我们是在 XML 文件中配置 CORS
现在可以通过实现WebMvcConfigurer接口然后重写addCorsMappings方法解决跨域问题。

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .maxAge(3600);
    }
}
spring-boot-starter-parent 有什么用?

新创建一个 SpringBoot 项目,默认都是有 parent 的,这个 parent 就是 spring-boot-starter-parent。

  • 定义了 Java 编译版本 。
  • 使用 UTF-8 格式编码。
  • 继承自 spring-boot-dependencies,这个里边定义了依赖的版本,也正是因为继承了这个依赖,所以我们在写依赖时才不需要写版本号。
  • 执行打包操作的配置。
  • 自动化的资源过滤。
  • 自动化的插件配置。
  • 针对 application.properties 和 application.yml 的资源过滤,包括通过 profile 定义的不同环境的配置文件,例如 application-dev.properties 和 application-dev.yml。
SpringBoot 打成的jar和普通的jar有什么区别 ?

SpringBoot的jar可以直接通过java -jar xxx.jar 命令来运行,但无法被其他项目依赖,主要还是他和普通jar的结构不同。
普通的jar包,解压后直接就是包名,包里就是我们的代码。
Spring Boot打包成的可执行jar解压后,在\BOOT-INF\classes 目录下才是我们的代码,因此无法被直接引用。如果非要引用,可以在 pom.xml 文件中增加配置,将 Spring Boot 项目打包成两个 jar ,一个可执行,一个可引用。

微服务中如何实现 session 共享?

在微服务中,一个完整的项目被拆分成多个不相同的独立的服务,各个服务独立部署在不同的服务器上,各自的 session 被从物理空间上隔离开了,但是经常,我们需要在不同微服务之间共享 session 。
常见的方案就是 Spring Session + Redis 来实现 session 共享。将所有微服务的 session 统一保存在 Redis 上,当各个微服务对 session 有相关的读写操作时,都去操作 Redis 上的 session 。这样就实现了 session 共享。

·····
内容后续不断更新中~~~

====================================================================

······
帮助他人,快乐自己,最后,感谢您的阅读!
所以如有纰漏或者建议,还请读者朋友们在评论区不吝指出!

个人网站…知识是一种宝贵的资源和财富,益发掘,更益分享…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值