原创

互联网大厂Java面试题集—Spring boot面试题(一)

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

可以不需要,内置了 Tomcat/ Jetty 等容器。通过pom.xml中导入依赖:

<!--spring-boot-starter-web:代表web模块,在这个模块中含了许多JAR包,-->
<!--有spring相关的jar,内置tomcat服务器,jackson等,这些web项目中常用的的功能都会自动引入-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

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

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

@SpringBootConfiguration

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

@ComponentScan:Spring组件扫描。

如何理解Spring Boot中Starters含义?

Starters是什么?

Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找示例代码和依赖包。如你想使用Spring JPA访问数据库,只要加入spring-boot-starter-data-jpa启动器依赖就能使用了。Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。

Starters命名?

Spring Boot官方的启动器都是以spring-boot-starter-命名的,代表了一个特定的应用类型。第三方的启动器不能以spring-boot开头命名,它们都被Spring Boot官方保留。一般一个第三方的应该这样命名,像mybatis的mybatis-spring-boot-starter

Starters分类:

1)Spring boot提供的启动器

启动器名称功能描述
spring-boot-starter核心模块,包含自动配置支持、日志库和对 YAML 配置文件的支持。
spring-boot-starter-amqp通过 spring-rabbit 来支持AMQP协议(Advanced Message Queuing Protocol)
spring-boot-starter-aop支持面向方面的编程即AOP,包括 spring-aop 和 AspectJ
spring-boot-starter-artemis通过 Apache Artemis 支持 JMS 的 API(Java Message Service API)
spring-boot-starter-batch支持 Spring Batch,包括 HSQLDB 数据库
spring-boot-starter-cache支持 Spring 的 Cache 抽象
spring-boot-starter-cloud-connectors支持 Spring Cloud Connectors,简化了在像 Cloud Foundry 或 Heroku 这样的云平台上连接服务
spring-boot-starter-data-elasticsearch支持 ElasticSearch 搜索和分析引擎,包括 spring-data-elasticsearch
spring-boot-starter-data-gemfire支持 GemFire 分布式数据存储,包括 spring-data-gemfire
spring-boot-starter-data-jpa支持 JPA(Java Persistence API),包括 spring-data-jpa、spring-orm、Hibernate
spring-boot-starter-data-solr支持 Apache Solr 搜索平台,包括 spring-data-solr
spring-boot-starter-data-mongodb支持MongoDB数据,包括spring-data-mongodb
spring-boot-starter-data-rest通过 spring-data-rest-webmvc,支持通过 REST 暴露 Spring Data 数据仓库
spring-boot-starter-redis支持 Redis 键值存储数据库,包括 spring-redis
spring-boot-starter-data-jdbc支持 JDBC 访问数据库
spring-boot-starter-jta-atomikos通过 Atomikos 支持 JTA 分布式事务处理
spring-boot-starter-jta-bitronix通过Bitronix支持JTA分布式事务处理
spring-boot-starter-security支持 spring-security
spring-boot-starter-test支持常规的测试依赖,包括JUnit、Hamcrest、Mockito以及spring-test模块
spring-boot-starter-velocity支持Velocity模板引擎
spring-boot-starter-freemarker支持 FreeMarker 模板引擎
spring-boot-starter-thymeleaf支持 Thymeleaf 模板引擎,包括与Spring的集成
spring-boot-starter-mustache支持 Mustache 模板引擎
spring-boot-starter-web支持全栈式 Web 开发,包括 Tomcat 和 spring-webmvc
spring-boot-starter-websocket支持 WebSocket 开发
spring-boot-starter-ws支持 Spring Web Services
spring-boot-starter-groovy-templates支持 Groovy 模板引擎
spring-boot-starter-hateoas通过 spring-hateoas 支持基于 HATEOAS 的 RESTful Web 服务
spring-boot-starter-hornetq通过 HornetQ 支持 JMS
spring-boot-starter-log4j支持 Log4J 日志框架
spring-boot-starter-logging引入了 Spring Boot 默认的日志框架 Logback
spring-boot-starter-integration支持通用的 spring-integration 模块
spring-boot-starter-jersey支持 Jersey RESTful Web 服务框架
spring-boot-starter-mail支持 javax.mail 模块
spring-boot-starter-mobile支持 spring-mobile
spring-boot-starter-social-facebook支持 spring-social-facebook
spring-boot-starter-social-linkedin支持 spring-social-linkedin
spring-boot-starter-social-twitter支持 spring-social-twitter
spring-boot-starter-actuator增加了面向产品上线相关的功能,比如测量和监控
spring-boot-starter-remote-shell增加了远程ssh shell的支持
spring-boot-starter-tomcat引入了 Spring Boot 默认的 HTTP 引擎 Tomcat
spring-boot-starter-jetty引入了Jetty HTTP引擎(用于替换Tomcat)
spring-boot-starter-undertow引入了Undertow HTTP引擎(用于替换Tomcat)

4)其他第三方启动器(略)

Spring Boot实现热部署有哪几种方式?

在Spring Boot实现代码热部署是一件很简单的事情,代码的修改可以自动部署并重新热启动项目。

1)引用devtools依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>

修改一个java类时就可以实现热更新了。

2)自定义配置热部署

以下配置用于自定义配置热部署,可以不设置。

#热部署开关,false即不启用热部署

spring.devtools.restart,enabled: true

#指定热部署的目录

#spring.devtools.restart.additional-paths: src/main/java

#指定目录不更新

spring.devtools.restart.exclude: test/**

3)Intellij Idea工具修改实现热部署

需要改以下两个位置:

勾上自动编译或者手动重新编译

File > Settings > Compiler-Build Project automatically

注册使用快捷键的方式:

ctrl + shift + alt + / > Registry > 勾选Compiler autoMake allow when app running

注意事项:

1)生产环境devtools将被禁用,如java -jar方式或者自定义的类加载器等都会识别为生产环境。

2)打包应用默认不会包含devtools,除非你禁用SpringBoot Maven插件的excludeDevtools属性。

3)Thymeleaf无需配置 spring.thymeleaf.cache:false,devtools默认会自动设置,参考完整属性。

下面是devtools自动配置的完整源码:

@Order(Ordered.LOWEST_PRECEDENCE)
public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostProcessor {
    private static final Map<String, Object> PROPERTIES;
    static {
Map<String, Object> devToolsProperties = new HashMap<>();
devToolsProperties.put("spring.thymeleaf.cache", "false");
devToolsProperties.put("spring.freemarker.cache", "false");
devToolsProperties.put("spring.groovy.template.cache", "false");
devToolsProperties.put("spring.mustache.cache", "false");
devToolsProperties.put("server.servlet.session.persistent", "true");
devToolsProperties.put("spring.h2.console.enabled", "true");
devToolsProperties.put("spring.resources.cache.period", "0");
devToolsProperties.put("spring.resources.chain.cache", "false");
devToolsProperties.put("spring.template.provider.cache", "false");
devToolsProperties.put("spring.mvc.log-resolved-exception", "true");
devToolsProperties.put("server.servlet.jsp.init-parameters.development", "true");
devToolsProperties.put("spring.reactor.stacktrace-mode.enabled", "true");
PROPERTIES = Collections.unmodifiableMap(devToolsProperties);
    }
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
    SpringApplication application) {
if (isLocalApplication(environment) && canAddProperties(environment)) {
    PropertySource<?> propertySource = new MapPropertySource("refresh",
    PROPERTIES);
    environment.getPropertySources().addLast(propertySource);
}
    }
    private boolean isLocalApplication(ConfigurableEnvironment environment) {
return environment.getPropertySources().get("remoteUrl") == null;
    }
    private boolean canAddProperties(Environment environment) {
return isRestarterInitialized() || isRemoteRestartEnabled(environment);
    }
    private boolean isRestarterInitialized() {
try {
    Restarter restarter = Restarter.getInstance();
    return (restarter != null && restarter.getInitialUrls() != null);
}
catch (Exception ex) {
    return false;
}
    }
    private boolean isRemoteRestartEnabled(Environment environment) {
return environment.containsProperty("spring.devtools.remote.secret");
    }
}

4)devtools会在windows资源管理器占用java进程,在开发工具里面杀不掉,只能手动kill掉,不然重启会选成端口重复绑定报错。

Spring Boot如何定义多套不同环境配置?

简单来说,Profile就是Spring Boot可以对不同环境或者指令来读取不同的配置文件。

假如有开发、测试、生产三个不同的环境,需要定义三个不同环境下的配置。

1)基于properties文件类型可以另外建立3个环境下的配置文件:

applcation.properties
application-dev.properties
application-test.properties
application-prod.properties

然后在applcation.properties文件中指定当前的环境spring.profiles.active=test,这时候读取的就是application-test.properties文件。

2)基于yml文件类型,只需要一个applcation.yml文件即可,推荐此方式。

spring:
  profiles: 
    active: prod
---
spring: 
  profiles: dev  
server: 
  port: 8080
  
---
spring: 
  profiles: test  
server: 
  port: 8081
---
spring.profiles: prod
spring.profiles.include:
  - proddb
  - prodmq
server: 
  port: 8082
  
---
spring: 
  profiles: proddb  
db:
name: mysql
   
---
spring: 
  profiles: prodmq   
mq: 
  address: localhost

 

其中dev代表开发,test代表测试,prod代表正式环境。此时读取的就是prod的配置,prod包含proddb,prodmq,此时可以读取proddb,prodmq下的配置。也可以同时激活三个配置,如下:

spring.profiles.active: prod,proddb,prodmq

3)基于Java代码,在JAVA配置代码中也可以加不同Profile下定义不同的配置文件,@Profile注解只能组合使用@Configuration@Component注解。

@Configuration
@Profile("prod")
public class ProductionConfiguration {
// ...
}

4)指定Profile

main方法启动方式:在Eclipse Arguments里面添加

--spring.profiles.active=prod

插件启动方式:

spring-boot:run -Drun.profiles=prod

jar运行方式:

java -jar xx.jar --spring.profiles.active=prod

除了在配置文件和命令行中指定Profile,还可以在启动类中写死指定,通过SpringApplication.setAdditionalProfiles方法。

SpringApplication.class
public void setAdditionalProfiles(String... profiles) {   
    this.additionalProfiles = new LinkedHashSet<String>(Arrays.asList(profiles));
}
~阅读全文~人机检测~

关注下方微信公众号“Java精选”(w_z90110),回复关键词领取资料:如Mysql、Hadoop、Dubbo、Spring Boot等,免费领取视频教程、资料文档和项目源码。

Java精选专注程序员推送一些Java开发知识,包括基础知识、各大流行框架(Mybatis、Spring、Spring Boot等)、大数据技术(Storm、Hadoop、MapReduce、Spark等)、数据库(Mysql、Oracle、NoSQL等)、算法与数据结构、面试专题、面试技巧经验、职业规划以及优质开源项目等。其中一部分由小编总结整理,另一部分来源于网络上优质资源,希望对大家的学习和工作有所帮助。

评论

分享:

支付宝

微信