springboot 面试题

什么是 Spring Boot?

SpringBoot 是 Spring 开源组织下的子项目,是 Spring 组件一站式解决方案,主要是简化了使用 Spring 的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。

为什么要用Spring Boot?

Spring Boot 优点非常多,如:

一、独立运行

Spring Boot而且内嵌了各种servlet容器,Tomcat、Jetty等,现在不再需要打成war包部署到容器中,Spring Boot只要打成一个可执行的jar包就能独立运行,所有的依赖包都在一个jar包内。

二、简化配置

spring-boot-starter-web启动器自动依赖其他组件,简少了maven的配置。

            <dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

             过去springmvc的时候或者ssm整合时,使用了大量包

三、自动配置

Spring Boot能根据当前类路径下的类、jar包来自动配置bean,如添加一个spring-boot-starter-web启动器就能拥有web的功能,无需其他配置。

四、无代码生成和XML配置

Spring Boot配置过程中无代码生成,也无需XML配置文件就能完成所有配置工作,这一切都是借助于条件注解完成的,这也是Spring4.x的核心功能之一。(@Conditional根据满足某一个特定条件创建一个特定的Bean。比如说,当某一个jar包在某一个类路径下的时候,自动配置一个或者多个Bean;或者只有某个Bean被创建才会创建另外一个Bean。总的来说,就是根据特定条件来控制Bean的创建行为,这样我们可以利用这个特性进行一些自动的配置。)

用法参考项目:conditional_demo

五、应用监控

Spring Boot提供一系列端点可以监控服务及应用,做健康检测。

Spring

Boot 的核心配置文件有哪几个?它们的区别是什么?

spring cloud官网:

https://cloud.spring.io/spring-cloud-static/Greenwich.SR1/single/spring-cloud.html#_the_bootstrap_application_context

Spring Boot 中有以下两种配置文件:

bootstrap (.yml 或者 .properties)

application (.yml 或者 .properties)

bootstrap/ application 的区别:

Spring Cloud 构建于Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap,,另外一种是application,,bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。bootstrap 主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。这两个上下文共用一个环境,它是任何Spring应用程序的外部属性的来源。bootstrap 里面的属性会优先加载,它们默认也不能被本地相同配置覆盖。

因此,对比 application 配置文件,bootstrap 配置文件具有以下几个特性:

boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载

boostrap 里面的属性不能被覆盖

bootstrap/ application 的应用场景:

application 配置文件这个容易理解,主要用于 Spring Boot 项目的自动化配置。

bootstrap 配置文件有以下几个应用场景:

使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息;

一些固定的不能被覆盖的属性

一些加密/解密的场景。


Spring

Boot 的配置文件有哪几种格式?它们有什么区别?

.properties 和 .yml,它们的区别主要是书写格式不同。

1).properties

server.port=8081

2).yml

server:

  port: 8082

另外,.yml 格式不支持 @PropertySource 注解导入配置。

yml的优先级高于.properties  可以两个配置文件中都配置访问端口号,看哪个配置生效

Spring

Boot 的核心注解是哪个?它主要由哪几个注解组成的?

启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解:

@SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能。

@EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = {

DataSourceAutoConfiguration.class })。

@ComponentScan:Spring组件扫描。


开启Spring Boot 特性有哪几种方式?

有以下两种方式:

1. 继承spring-boot-starter-parent项目(普通spring-boot项目)

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.2.4.RELEASE</version>

<relativePath/> <!-- lookup parent from

repository -->

</parent>

2. 导入spring-boot-dependencies项目依赖(参考时springcloud项目搭建的方法)

<dependencyManagement>

                org.springframework.boot

                spring-boot-dependencies

                ${spring-boot.version}

                 pom

                import

</dependencyManagement>

     dependencyManagement和 dependencies区别

               dependencyManagement当使用父子项目创建工程架构时,父项目可以使用该标签

               来规定子项目可以使用哪些包,但是并不是直接引入,而是子项目按需引入,并且引入

               时不需要加版本号

               dependencies使用的话,直接父项目把所有包都引入了,不管子项目是否用得到

         import  maven默认也是单继承  加上import  相当于父项目中使用了

         多继承,既有springcloud的所有包,又有springboot的所有包,子项目,可以直接使用

Spring Boot依赖注意点:

1. 属性覆盖只对继承有效

Spring Boot依赖包里面的组件的版本都是和当前Spring

Boot绑定的,如果要修改里面组件的版本,只需要添加如下属性覆盖即可,但这种方式只对继承有效,导入的方式无效。

<properties>

   1.7.25

</properties>


如果导入的方式要实现版本的升级,达到上面的效果,这样也可以做到,把要升级的组件依赖放到Spring Boot之前。需要注意,要修改Spring Boot的依赖组件版本可能会造成不兼容的问题。

Spring

Boot 需要独立的容器运行吗?

可以不需要,内置了 Tomcat/Jetty 等容器。

模拟内置tomcat功能,参考项目:embed_tomcat

      1,创建普通的java项目


      2,引入jar包

                        <dependency>

     org.apache.tomcat.embed

     tomcat-embed-core

     8.5.51

     org.apache.tomcat.embed

     tomcat-embed-el

     8.5.51

     org.apache.tomcat.embed

     tomcat-embed-jasper

     8.5.51

      3,编写启动类

             package com.aaa;

import

org.apache.catalina.Context;

import

org.apache.catalina.WebResourceRoot;

import

org.apache.catalina.startup.Tomcat;

import

org.apache.catalina.webresources.DirResourceSet;

import

org.apache.catalina.webresources.StandardRoot;

import

java.io.File;

/**

 * fileName:SpringApplication

 * description:

 * author:zz

 * createTime:2020/2/26 18:17

 * version:1.0.0

 */

public

class SpringApplication {

    /**

     *模拟内置tomcat

     */

    public static void run(){

        //创建tomcat实例

        Tomcat tom = new Tomcat();

        //设置端口

        tom.setPort(8888);

        try{

            //获取项目编译后的class 路径

            String path =SpringApplication.class.getResource("/").getPath();

            //获取webapp 文件D:\idea_qy107\embed_tomcat\src\main\webapp

            String filePath = newFile("src/main/webapp").getAbsolutePath();

           //然后将webapp下的项目添加至tomcat的context容器(context对应一个运行的项目)

            Context context=tom.addWebapp("/my_web_app",filePath);

            //参数1:一般是项目名 对应请求url中的项目名

            //webResourceRoot用于加载 项目的class文件

           WebResourceRoot webResource = newStandardRoot(context);

           webResource.addPreResources(newDirResourceSet(webResource,"/WEB-INF/classes",path,"/"));

           tom.start();

        }catch (Exception e) {

            e.printStackTrace();

        }

        //阻塞

,等待前端连接

        tom.getServer().await();

    }

}

运行 Spring Boot 有哪几种方式?

1)打包用命令或者放到容器中运行



在jar所在位置,shift+鼠标右键    打开命令行,输入命令:

java -jar  spring_boot_interview_question.jar  [启动类]


2)用 Maven/Gradle 插件运行

     进入项目目录,执行下面命令


      mvn spring-boot:run

启动测试:

http://localhost:8082/showEntity

     ctrl+c终止运行,如果是cmd命令窗口,直接关闭就可以了

3)直接执行main 方法运行


Spring

Boot 自动配置原理是什么?

为自动配置做铺垫:

  @import三种用法:

       直接将pojo类注入到Spring IOC容器

          1, 创建java类:

public class PojoClass {

    //空构造

   public PojoClass() {

       System.out.println("PojoClass交给了spirngioc管理了。。。 ");

    }

}

   2,在@Configuration注解的类上加入@Import(value = {PojoClass.class})

   3,测试

         把它注入到任意一个已经交给spring管理的类中

         @Autowired

             private PojoClass pojoClass;

     public Emp getById(Integer empNo){

       System.out.println("springioc容器中是否存在pojoClass对象:"+pojoClass);

       return empService.getById(empNo);

     }

       通过ImportBeanDefinitionRegistrar将类注入到Spring IOC容器。

 1, 创建java类:

            public class BeanDefinitionRegisterClass {

   public BeanDefinitionRegisterClass() {

       System.out.println("通过ImportBeanDefinitionRegistrar接口把该类交给springioc容器进行管理。。。");

    }

}

2,创建ImportBeanDefinitionRegistrar实现类

 public class MyImportBeanDefinitionRegisterimplements ImportBeanDefinitionRegistrar {

    @Override

    public voidregisterBeanDefinitions(AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry) {

        //交给springioc容器管理的是BeanDefinition bean定义

        RootBeanDefinition rootBeanDefinition=new RootBeanDefinition(BeanDefinitionRegisterClass.class);

       registry.registerBeanDefinition("beanDefinitionRegisterClass",rootBeanDefinition);

    }

}

3,在@Configuration注解的类上加入@Import(value ={MyImportBeanDefinitionRegister.class})

4,测试

  @Autowired

   private BeanDefinitionRegisterClass beanDefinitionRegisterClass;

 publicEmp getById(Integer empNo){

       System.out.println("springioc容器中是否存在pojoClass对象:"+pojoClass);

       System.out.println("springioc容器中是否存在beanDefinitionRegisterClass对象:"+beanDefinitionRegisterClass);

       return empService.getById(empNo);

    }

   通过ImportSelector方式注入Bean

             1,创建多个java类

             publicclass ImportSelectorClassA {

   public ImportSelectorClassA() {

       System.out.println("通过ImportSelector接口把该类ImportSelectorClassA交给springioc容器进行管理。。。");

    }

}

             2,创建ImportSelector的实现类

                public class MyImportSelector implements ImportSelector {

   @Override

   public String[] selectImports(AnnotationMetadata annotationMetadata) {

       return newString[]{"com.aaa.sbac.ac2.entity.ImportSelectorClassA",

       "com.aaa.sbac.ac2.entity.ImportSelectorClassB"};

    }

}

      3,在@Configuration注解的类上加入@Import(value ={MyImportSelector.class})

       4,测试

                 测试同上

参考项目:spring_boot_auto_configuration第3个例子:com.aaa.sbac.ac3包的例子:

Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射。



URL url =

urls.nextElement();

这个方法会加载类路径及所有jar包下META-INF/spring.factories配置中映射的自动配置的类。

public

static final String FACTORIES_RESOURCE_LOCATION =

"META-INF/spring.factories";

查看Spring

Boot自带的自动配置的包:org.springframework.boot:spring-boot-autoconfigure-2.2.4.RELEASE.jar,打开其中的META-INF/spring.factories文件会找到自动配置的映射。

再来看看数据源自动配置的实现注解

@Configuration,@ConditionalOnClass就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容