Springboot的優點
- 內置servlet容器,不需要在服務器部署 tomcat,只需要將專案打成 jar 包,使用 java -jar xxx.jar一鍵式啟動專案
- SpringBoot提供了starter,把常用庫聚合在一起,簡化復雜的環境配置,快速搭建spring應用環境
- 可以快速創建獨立運行的spring專案,集成主流框架
- 準生產環境的運行應用監控
SpringBoot 中的 starter 到底是什么 ?
starter提供了一個自動化配置類,一般命名為 XXXAutoConfiguration ,在這個配置類中通過條件注解來決定一個配置是否生效(條件注解就是 Spring 中原本就有的),然后它還會提供一系列的默認配置,也允許開發者根據實際情況自定義相關配置,然后通過型別安全的屬性注入將這些配置屬性注入進來,新注入的屬性會代替掉默認屬性,正因為如此,很多第三方框架,我們只需要引入依賴就可以直接使用了,
運行 SpringBoot 有哪幾種方式?
- 打包用命令或者者放到容器中運行
- 用 Maven/Gradle 插件運行
- 直接執行 main 方法運行
SpringBoot 常用的 Starter 有哪些?
- spring-boot-starter-web :提供 Spring MVC + 內嵌的 Tomcat ,
- spring-boot-starter-data-jpa :提供 Spring JPA + Hibernate ,
- spring-boot-starter-data-Redis :提供 Redis ,
- mybatis-spring-boot-starter :提供 MyBatis ,
Spring Boot 的核心注解是哪個?
啟動類上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要組合包含了以下 3 個注解:
- @SpringBootConfiguration:組合了 @Configuration 注解,實作組態檔的功能,
- @EnableAutoConfiguration:打開自動配置的功能,也可以關閉某個自動配置的選項,如關閉資料源自動配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }),
- @ComponentScan:Spring組件掃描,
本文已經收錄到Github倉庫,該倉庫包含計算機基礎、Java基礎、多執行緒、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~
Github地址
如果訪問不了Github,可以訪問gitee地址,
gitee地址
自動配置原理
SpringBoot實作自動配置原理圖解:
在 application.properties 中設定屬性 debug=true,可以在控制臺查看已啟用和未啟用的自動配置,
@SpringBootApplication是@Configuration、@EnableAutoConfiguration和@ComponentScan的組合,
@Configuration表示該類是Java配置類,
@ComponentScan開啟自動掃描符合條件的bean(添加了@Controller、@Service等注解),
@EnableAutoConfiguration會根據類路徑中的jar依賴為專案進行自動配置,比如添加了spring-boot-starter-web
依賴,會自動添加Tomcat和Spring MVC的依賴,然后Spring Boot會對Tomcat和Spring MVC進行自動配置(spring.factories EnableAutoConfiguration配置了WebMvcAutoConfiguration
),
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
EnableAutoConfiguration主要由 @AutoConfigurationPackage,@Import(EnableAutoConfigurationImportSelector.class)這兩個注解組成的,
@AutoConfigurationPackage用于將啟動類所在的包里面的所有組件注冊到spring容器,
@Import 將EnableAutoConfigurationImportSelector注入到spring容器中,EnableAutoConfigurationImportSelector通過SpringFactoriesLoader從類路徑下去讀取META-INF/spring.factories檔案資訊,此檔案中有一個key為org.springframework.boot.autoconfigure.EnableAutoConfiguration,定義了一組需要自動配置的bean,
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
這些配置類不是都會被加載,會根據xxxAutoConfiguration上的@ConditionalOnClass等條件判斷是否加載,符合條件才會將相應的組件被加載到spring容器,(比如mybatis-spring-boot-starter,會自動配置sqlSessionFactory、sqlSessionTemplate、dataSource等mybatis所需的組件)
最全面的Java面試網站
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,
AnnotatedElement.class }) //類路徑存在EnableAspectJAutoProxy等類檔案,才會加載此配置類
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "https://www.cnblogs.com/tyson03/p/true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "https://www.cnblogs.com/tyson03/p/false", matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "https://www.cnblogs.com/tyson03/p/true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
全域組態檔中的屬性如何生效,比如:server.port=8081,是如何生效的?
@ConfigurationProperties的作用就是將組態檔的屬性系結到對應的bean上,全域配置的屬性如:server.port等,通過@ConfigurationProperties注解,系結到對應的XxxxProperties bean,通過這個 bean 獲取相應的屬性(serverProperties.getPort()),
//server.port = 8080
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
private Integer port;
private InetAddress address;
@NestedConfigurationProperty
private final ErrorProperties error = new ErrorProperties();
private Boolean useForwardHeaders;
private String serverHeader;
//...
}
實作自動配置
實作當某個類存在時,自動配置這個類的bean,并且可以在application.properties中配置bean的屬性,
(1)新建Maven專案spring-boot-starter-hello,修改pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tyson</groupId>
<artifactId>spring-boot-starter-hello</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.3.0.M1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
</project>
(2)屬性配置
public class HelloService {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String sayHello() {
return "hello" + msg;
}
}
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix="hello")
public class HelloServiceProperties {
private static final String MSG = "world";
private String msg = MSG;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
(3)自動配置類
import com.tyson.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(HelloServiceProperties.class) //1
@ConditionalOnClass(HelloService.class) //2
@ConditionalOnProperty(prefix="hello", value = "https://www.cnblogs.com/tyson03/p/enabled", matchIfMissing = true) //3
public class HelloServiceAutoConfiguration {
@Autowired
private HelloServiceProperties helloServiceProperties;
@Bean
@ConditionalOnMissingBean(HelloService.class) //4
public HelloService helloService() {
HelloService helloService = new HelloService();
helloService.setMsg(helloServiceProperties.getMsg());
return helloService;
}
}
-
@EnableConfigurationProperties 注解開啟屬性注入,將帶有@ConfigurationProperties 注解的類注入為Spring 容器的 Bean,
-
當 HelloService 在類路徑的條件下,
-
當設定 hello=enabled 的情況下,如果沒有設定則默認為 true,即條件符合,
-
當容器沒有這個 Bean 的時候,
(4)注冊配置
想要自動配置生效,需要注冊自動配置類,在 src/main/resources 下新建 META-INF/spring.factories,添加以下內容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.tyson.config.HelloServiceAutoConfiguration
"\"是為了換行后仍然能讀到屬性,若有多個自動配置,則用逗號隔開,
(5)使用starter
在 Spring Boot 專案的 pom.xml 中添加:
<dependency>
<groupId>com.tyson</groupId>
<artifactId>spring-boot-starter-hello</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
運行類如下:
import com.tyson.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class SpringbootDemoApplication {
@Autowired
public HelloService helloService;
@RequestMapping("/")
public String index() {
return helloService.getMsg();
}
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}
在專案中沒有配置 HelloService bean,但是我們可以注入這個bean,這是通過自動配置實作的,
在 application.properties 中添加 debug 屬性,運行配置類,在控制臺可以看到:
HelloServiceAutoConfiguration matched:
- @ConditionalOnClass found required class 'com.tyson.service.HelloService' (OnClassCondition)
- @ConditionalOnProperty (hello.enabled) matched (OnPropertyCondition)
HelloServiceAutoConfiguration#helloService matched:
- @ConditionalOnMissingBean (types: com.tyson.service.HelloService; SearchStrategy: all) did not find any beans (OnBeanCondition)
可以在 application.properties 中配置 msg 的內容:
hello.msg=大彬
@Value注解的原理
@Value的決議就是在bean初始化階段,BeanPostProcessor定義了bean初始化前后用戶可以對bean進行操作的介面方法,它的一個重要實作類AutowiredAnnotationBeanPostProcessor
為bean中的@Autowired和@Value注解的注入功能提供支持,
Spring Boot 需要獨立的容器運行嗎?
不需要,內置了 Tomcat/ Jetty 等容器,
Spring Boot 支持哪些日志框架?
Spring Boot 支持 Java Util Logging, Log4j2, Lockback 作為日志框架,如果你使用 Starters 啟動器,Spring Boot 將使用 Logback 作為默認日志框架,但是不管是那種日志框架他都支持將組態檔輸出到控制臺或者檔案中,
YAML 配置的優勢在哪里 ?
YAML 配置和傳統的 properties 配置相比之下,有這些優勢:
- 配置有序
- 簡潔明了,支持陣列,陣列中的元素可以是基本資料型別也可以是物件
缺點就是不支持 @PropertySource 注解匯入自定義的 YAML 配置,
什么是 Spring Profiles?
在專案的開發中,有些組態檔在開發、測驗或者生產等不同環境中可能是不同的,例如資料庫連接、redis的配置等等,那我們如何在不同環境中自動實作配置的切換呢?Spring給我們提供了profiles機制給我們提供的就是來回切換組態檔的功能
Spring Profiles 允許用戶根據組態檔(dev,test,prod 等)來注冊 bean,因此,當應用程式在開發中運行時,只有某些 bean 可以加載,而在 PRODUCTION中,某些其他 bean 可以加載,假設我們的要求是 Swagger 檔案僅適用于 QA 環境,并且禁用所有其他檔案,這可以使用組態檔來完成,Spring Boot 使得使用組態檔非常簡單,
SpringBoot多資料源事務如何管理
第一種方式是在service層的@TransactionManager中使用transactionManager指定DataSourceConfig中配置的事務,
第二種是使用jta-atomikos實作分布式事務管理,
spring-boot-starter-parent 有什么用 ?
新創建一個 Spring Boot 專案,默認都是有 parent 的,這個 parent 就是 spring-boot-starter-parent ,spring-boot-starter-parent 主要有如下作用:
- 定義了 Java 編譯版本,
- 使用 UTF-8 格式編碼,
- 執行打包操作的配置,
- 自動化的資源過濾,
- 自動化的插件配置,
- 針對 application.properties 和 application.yml 的資源過濾,包括通過 profile 定義的不同環境的組態檔,例如 application-dev.properties 和 application-dev.yml,
Spring Boot 打成的 jar 和普通的 jar 有什么區別 ?
- Spring Boot 專案最終打包成的 jar 是可執行 jar ,這種 jar 可以直接通過
java -jar xxx.jar
命令來運行,這種 jar 不可以作為普通的 jar 被其他專案依賴,即使依賴了也無法使用其中的類, - Spring Boot 的 jar 無法被其他專案依賴,主要還是他和普通 jar 的結構不同,普通的 jar 包,解壓后直接就是包名,包里就是我們的代碼,而 Spring Boot 打包成的可執行 jar 解壓后,在
\BOOT-INF\classes
目錄下才是我們的代碼,因此無法被直接參考,如果非要參考,可以在 pom.xml 檔案中增加配置,將 Spring Boot 專案打包成兩個 jar ,一個可執行,一個可參考,
SpringBoot多資料源拆分的思路
先在properties組態檔中配置兩個資料源,創建分包mapper,使用@ConfigurationProperties讀取properties中的配置,使用@MapperScan注冊到對應的mapper包中 ,
最后給大家分享一個Github倉庫,上面有大彬整理的300多本經典的計算機書籍PDF,包括C語言、C++、Java、Python、前端、資料庫、作業系統、計算機網路、資料結構和演算法、機器學習、編程人生等,可以star一下,下次找書直接在上面搜索,倉庫持續更新中~
Github地址
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/548769.html
標籤:Java
上一篇:java魔功心法-范型篇