你觉得 SpringBoot 最大的优势是什么呢?
答:SpringBoot 的最大的优势是“约定优于配置“。“约定优于配置“是一种软件设计范式,开发人员按照约定的方式来进行编程,可以减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。
SpringBoot 中 “约定优于配置“的具体产品体现在哪里?
答:SpringBoot Starter、SpringBoot Jpa 都是“约定优于配置“的一种体现。都是通过“约定优于配置“的设计思路来设计的,SpringBoot Starter 在启动的过程中会根据约定的信息对资源进行初始化;SpringBoot Jpa 通过约定的方式来自动生成 Sql ,避免大量无效代码编写。
SpringBoot Starter 的工作原理是什么?
答: SpringBoot 在启动的时候,按照约定去读取 SpringBoot Starter 的配置信息,再根据配置信息对资源进行初始化,并注入到 Spring 容器中。这样 SpringBoot 启动完毕后,就已经准备好了一切资源,使用过程中直接注入对应 Bean 资源即可。
具体干了这几件事情:
-
① SpringBoot 在启动时会去依赖的 Starter 包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的 Jar 包去扫描项目所依赖的 Jar 包。
-
② 根据 spring.factories 配置加载 AutoConfigure 类
-
③ 根据 @Conditional 注解的条件,进行自动配置并将 Bean 注入 Spring Context
SpringBoot 的自动配置是如何实现的?
SpringBoot 项目的启动注解是:@SpringBootApplication,是一个复合注解,由下面三个注解组成的:
-
@EnableAutoConfiguration
- @ComponentScan
- @Configuration
其中 @EnableAutoConfiguration注解是实现自动配置的入口,该注解又通过 @Import 注解导入了AutoConfigurationImportSelector类,在AutoConfigurationImportSelector类中加载 META-INF/spring.factories 的配置信息,然后筛选出以 EnableAutoConfiguration 为 key 的数据,加载到 IOC 容器中,实现自动配置功能!
方便理解记忆链条:
@EnableAutoConfiguration注解自动配置入口 -> @Import 注解 导入了AutoConfigurationImportSelector类 -> AutoConfigurationImportSelector类中加载 META-INF/spring.factories 配置 -> 筛选出以 EnableAutoConfiguration 为 key 的数据,加载到 IOC 容器中实现自动配置
什么是嵌入式服务器?我们为什么要使用嵌入式服务器呢?
思考一下在你的虚拟机上部署应用程序需要些什么。
第一步:安装 Java
第二部:安装 Web 或者是应用程序的服务器(Tomat/Wbesphere/Weblogic 等等)
第三部:部署应用程序 war 包
如果我们想简化这些步骤,应该如何做呢?
让我们来思考如何使服务器成为应用程序的一部分?
你只需要一个安装了 Java 的虚拟机,就可以直接在上面部署应用程序了,
是不是很爽?
这个想法是嵌入式服务器的起源。
什么是嵌入式服务器:
当我们创建一个可以部署的应用程序的时候,我们将会把服务器(例如,tomcat)嵌入到可部署的服务器中,这就是嵌入式服务器。
例如,对于一个 SpringBoot 应用程序来说,你可以生成一个包含 Embedded Tomcat 的应用程序 jar。你就可以像运行正常 Java 应用程序一样来运行 web 应用程序了。
嵌入式服务器就是我们的可执行单元包含服务器的二进制文件(例如,tomcat.jar)。
使用嵌入式服务器的好处:
可以简化传统部署应用程序的步骤,只需要安装Java虚拟机,然后直接部署应用程序即可。
SpringBoot 如何设置支持跨域请求?
现代浏览器出于安全的考虑, HTTP 请求时必须遵守同源策略,否则就是跨域的 HTTP 请求,默认情况下是被禁止的,IP(域名)不同、或者端口不同、协议不同(比如 HTTP、HTTPS)都会造成跨域问题。
一般前端的解决方案有:
-
① 使用 JSONP 来支持跨域的请求,JSONP 实现跨域请求的原理简单的说,就是动态创建
<script>
标签,然后利用<script>
的 SRC 不受同源策略约束来跨域获取数据。缺点是需要后端配合输出特定的返回信息。 -
② 利用反应代理的机制来解决跨域的问题,前端请求的时候先将请求发送到同源地址的后端,通过后端请求转发来避免跨域的访问。
后来 HTML5 支持了 CORS 协议。CORS 是一个 W3C 标准,全称是”跨域资源共享”(Cross-origin resource sharing),允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 AJAX 只能同源使用的限制。它通过服务器增加一个特殊的 Header[Access-Control-Allow-Origin]来告诉客户端跨域的限制,如果浏览器支持 CORS、并且判断 Origin 通过的话,就会允许 XMLHttpRequest 发起跨域请求。
前端使用了 CORS 协议,就需要后端设置支持非同源的请求,SpringBoot 设置支持非同源的请求有两种方式。
第一,配置 CorsFilter。
1 @Configuration 2 public class GlobalCorsConfig { 3 @Bean 4 public CorsFilter corsFilter() { 5 CorsConfiguration config = new CorsConfiguration(); 6 config.addAllowedOrigin("*"); 7 config.setAllowCredentials(true); 8 config.addAllowedMethod("*"); 9 config.addAllowedHeader("*"); 10 config.addExposedHeader("*"); 11 12 UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); 13 configSource.registerCorsConfiguration("/**", config); 14 15 return new CorsFilter(configSource); 16 } 17 }
需要配置上述的一段代码。第二种方式稍微简单一些。
第二,在启动类上添加:
public class Application extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowCredentials(true) .allowedHeaders("*") .allowedOrigins("*") .allowedMethods("*"); } }
Spring 、SpringBoot 和 SpringCloud 的关系?
Spring 最初最核心的两大核心功能 Spring Ioc 和 Spring Aop 成就了 Spring,Spring 在这两大核心的功能上不断的发展,才有了 Spring 事务、Spring Mvc 等一系列伟大的产品,最终成就了 Spring 帝国,到了后期 Spring 几乎可以解决企业开发中的所有问题。
SpringBoot 是在强大的 Spring 帝国生态基础上面发展而来,发明 SpringBoot 不是为了取代 Spring ,是为了让人们更容易的使用 Spring 。
SpringCloud 是一个微服务治理框架,基于SpringBoot实现,它利用 SpringBoot 的开发便利性巧妙地简化了分布式系统基础设施的开发。如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 SpringBoot 的开发风格做到一键启动和部署。
SpringCloud 是为了解决微服务架构中服务治理而提供的一系列功能的开发框架,并且 SpringCloud 是完全基于 SpringBoot 而开发,SpringCloud 利用 SpringBoot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案。
用一组不太合理的包含关系来表达它们之间的关系。
Spring ioc/aop > Spring > SpringBoot > SpringCloud
JPA 和 Hibernate 有哪些区别?JPA 可以支持动态 SQL 吗?
JPA本身是一种ORM规范(不是ORM框架,因为JPA并未提供ORM实现,只是制定了规范)因为JPA是一种规范,所以,只是提供了一些相关的接口,但是接口并不能直接使用,JPA底层需要某种JPA实现,Hibernate 是 JPA 的一个实现集。
JPA 是根据实体类的注解来创建对应的表和字段,如果需要动态创建表或者字段,需要动态构建对应的实体类,再重新调用Jpa刷新整个Entity。动态SQL,mybatis支持的最好,jpa也可以支持,但是没有Mybatis那么灵活。
shiro和oauth还有cas他们之间的关系是什么?问下您公司权限是如何设计,还有就是这几个概念的区别。
cas和oauth是一个解决单点登录的组件,shiro主要是负责权限安全方面的工作,所以功能点不一致。但往往需要单点登陆和权限控制一起来使用,所以就有 cas+shiro或者oauth+shiro这样的组合。
token一般是客户端登录后服务端生成的令牌,每次访问服务端会进行校验,一般保存到内存即可,也可以放到其他介质;redis可以做Session共享,如果前端web服务器有几台负载,但是需要保持用户登录的状态,这场景使用比较常见。
我们公司使用oauth+shiro这样的方式来做后台权限的管理,oauth负责多后台统一登录认证,shiro负责给登录用户赋予不同的访问权限。
各服务之间通信,对Restful和Rpc这2种方式如何做选择?
在传统的SOA治理中,使用rpc的居多;SpringCloud默认使用restful进行服务之间的通讯。rpc通讯效率会比restful要高一些,但是对于大多数公司来讲,这点效率影响甚微。我建议使用restful这种方式,易于在不同语言实现的服务之间通讯。