一、SpringBoot基礎介紹
SpringBoot是基於Spring Framework框架上擴展而來的,是爲了快速構建Spring應用程序的工具。SpringBoot嵌入了Tomcat、Jetty、Undertow等容器,無需部署WAR包,簡化了Maven配置。SpringBoot實現了自動化配置Spring,無代碼生成和xml配置。
啓動過程
SpringBoot容器是通過Java的main方法開始的。分爲以下幾步:
- 註解掃描、載入自動配置bean,將所有符合自動配置條件的bean定義加載到IoC容器
- 調用SpringApplication.run()具體容器啓動流程
- 獲取監聽器SpringApplicationRunListeners
- listeners.starting(),觸發ApplicationStartedEvent事件
- 準備好環境,觸發ApplicationEnvironmentPreparedEvent事件
- 打印啓動提示符,默認Spring的字符圖
- 實例化一個可配置應用上下文ConfigurableApplicationContext
- 準備上下文listeners,出發ApplicationPreparedEvent事件
- 刷新上下文 AbstractApplicationContext.Refresh()
- 刷新上下文後;執行啓動執行器ApplicationRunner/CommandLineRunner用戶可擴展接口
- 成功觸發事件ApplicationReadyEvent,遇到異常出發ApplicationFailedEvent
多環境配置文件
SpringBoot的多環境配置文件需要使用application-{profile}.properties的格式,這裏的{profile}是環境標誌,例如dev, test, prod。我們需要在application.properties中添加配置項spring.profiles.active=def,也可以在IDEA的Run/Debug Configuration中添加SpringBoot應用,選擇main類並選擇對應的Active Profiles。
配置文件語法
SpringBoot有兩種配置文件,一種是properties文件,另一種是yml文件。yml文件的好處是層次結構比較清晰,但對格式和縮進的要求比較高,否則加載會失敗。一般情況下,建議使用yml文件。
常用啓動器
SpringBoot有非常多的啓動器,它們負責把我們需要的依賴打包好下載下來,省去我們自己配置的麻煩。
名稱 | 用途 |
---|---|
spring-boot-starter-web | 嵌入Tomcat和Web開發需要的Servlet和JSP |
spring-boot-starter-thymeleaf | Thymeleaf視圖構建MVC Web應用程序 |
spring-boot-starter-data-redis | 緩存redis操作支持 |
spring-boot-starter-data-jpa | 數據庫JPA操作支持 |
spring-boot-starter-data-elasticsearch | Elasticsearch搜索和分析引擎和Spring Data Elasticsearch支持 |
spring-boot-starter-data-mongodb | MongoDB數據庫操作支持 |
spring-boot-starter-test | 單元測試 |
spring-boot-starter-jdbc | JDBC數據庫操作支持 |
spring-boot-starter-aop | AOP切面編程支持 |
spring-boot-starter-security | Spring Security安全控制支持者 |
spring-boot-starter-actuator | 健康監控支持 |
spring-boot-starter-tomcat | Tomcat作爲默認的嵌入式容器,其他的還有Jetty和Undertow |
mybatis-spring-boot-starter | 第三方MyBatis操作數據庫支持 |
常用註解
SpringBoot有一些常用的註解,有些是來自Spring和SpringMVC的
註解 | 用途 |
---|---|
@SprigBootApplication | 複合註解,包括@ComponentScan,@SpringBootConfiguration,@EnableAutoConguration |
@ResponseBody | 直接將返回結果寫入HTTP Response Body,一般在異步獲取數據時使用 |
@Controller | 定義控制類,通常需要配合@RequestMapping |
@RestController | 相當於@ResponseBody + @Controller |
@Service | 用於修飾服務層組件 |
@Repository | 用於修飾數據持久層組件 |
@Bean | 用@Bean標註等價於Xml中配置bean |
@Value | 注入SpringBoot Application.properties配置的屬性的值 |
二、SpringBoot開發實踐
在IDEA中,新建項目,選擇Spring Initializr,其中已經內嵌了Maven 3。在該項目中,初始環境選擇了Web下的Spring Web選項和lombok工具包來使用log。
我們首先看一下項目的結構,Application對應的是主函數,也就是負責啓動的類。在resources下的static包和templates包放的是靜態文件,static包放的是js/css/images等文件,templates包下放的是HTML文件。application.properties是SpringBoot的配置文件。
我們再查看一下Maven的pom.xml文件,其中的依賴項已經配置好了
1. HelloWorld
當前項目已經可以啓動了,Tomcat的監聽端口是8080。我們首先寫一個Controller,Controller通常使用的有@RestController註解和@RequestMapping註解
@RestController
@RequestMapping("/api/demo/")
public class HelloController {
@RequestMapping(value = "/hello")
public String hello(HttpServletRequest req, HttpServletResponse resp){
return "Hello World! Welcome to SpringBoot";
}
}
啓動Application後,訪問http://localhost:8080/api/demo/hello即可訪問到輸出的內容
2. 更換容器
SpringBoot默認的容器爲Tomcat,但實際還上使用Undertow或者其他框架作爲容器。因此我們嘗試着更換一下容器。我們首先要把SpringBoot依賴中的Tomcat排除掉,並添加Undertow依賴。
我們首先把spring-boot-starter-web依賴項添加<exclusion>選項來排除Tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
此時我們的項目沒有容器可以使用了,現在我們在<dependencies>中添加Undertow依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
3. 整合MyBatis做CRUD
當然,剛纔的例子比較簡單。下面我們實現一個通過MyBatis和SpringBoot實現對數據庫進行增刪改查的操作。首先我們來添加依賴項
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
我們使用MyBatis的Generator插件,因此還要添加插件。MyBatis Generator可以直接生成Bean類和Mapper,無需自己手動添加。在<plugins>…<\plugins>中添加
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.6</version>
</plugin>
還需要在resources中添加MyBatis Generator的配置文件,這一部分網上教程有很多,不再贅述了。在配置好後,選擇Maven - Plugin - MyBatis Generator - mybatis-generator: generate,運行後顯示BUILD SUCCESS即爲成功。
我們使用MyBatis Generator的另一個目的是使用Example,由06和07兩篇文章我們瞭解到MyBatis的動態SQL支持動態語句查詢,但效率比較慢,因此我們使用Example來實現相同的功能。
我們需要在SpringBoot的application.properties中添加關於數據庫的配置
spring.datasource.url=jdbc:mysql://localhost:3306/boss?characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
另外記得要在Application類中添加註解@MapperScan(),其中要寫mapper類的地址,我們寫根目錄即可。
下面編寫一個Controller
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
TUserMapper tUserMapper;
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
public TUser findById(HttpServletRequest req, HttpServletResponse resp,
@PathVariable("id") int userId){
return tUserMapper.selectByPrimaryKey(userId);
}
}
如果無法Autowired的話記得要給Mapper類添加@Service註解
4. AOP實現添加日誌
我們還可以使用前面提到過的切面編程來實現對操作添加日誌。首先添加aop相關的依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
我們來實現切面功能類
@Component
@Aspect
@Slf4j
public class WebRequestLog {
@Pointcut("execution(public * com.dai.learning.springboot.controller..*.*(..))")
public void pointcut(){
// 切入點
}
@Before("pointcut()")
public void doBefore(JoinPoint joinPoint) throws Exception{
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
log.info("URL: "+request.getRequestURL().toString());
log.info("Http Method:" + request.getMethod());
log.info("IP: "+request.getRemoteAddr());
log.info("Class Method:" + joinPoint.getSignature().getDeclaringTypeName());
}
@AfterReturning(returning = "result", pointcut = "pointcut()")
public void doAfterReturning(Object result){
log.info("Return of the method: "+result.toString());
}
}
之後調用其他Controller方法時就會返回對應的日誌了。
三、SpringBoot應用部署
下面我們來看看如何進行SpringBoot的應用部署,讓其他用戶可以訪問到。我們首先在Maven中執行clean,在執行package打包,看到BUILD SUCCESS即爲打包成功。在項目路徑的target下可以看到打包完畢的jar包。
我們新建一個deploy目錄,並將jar包放在其中。我們新建一個啓動腳本
在Windows下需要新建一個bat文件,在Linux下需要新建一個.sh文件
java -jar demo-0.0.1.jar
注意,添加的是打包成功的對應的jar包名稱。之後我們執行啓動腳本文件,在加載成功後,SpringBoot的應用即可正常使用。
當然,這是最基礎的部署方式,還可以使用Docker和K8s來進行部署,在這裏不做介紹。
隨着項目的發展,項目的規模會越來越大,其中的配置文件也需要進行調整。當我們需要更新的時候,如果我們可以只把更新的部分部署就好了,因此下面我們來看看如何自定義結構來進行打包。
打開Maven的pom.xml文件,我們首先需要在<build>下添加<resources>節點,並將裏面的內容進行排除
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<exclude>*</exclude>
</resource>
</resources>
</build>
我們再添加maven的插件
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layout>zip</layout>
<excludeGroupIds>
[運行mvn dependency:tree的結果]
</excludeGroupIds>
<executions>
<execution>
<goal>repackage</goal>
</execution>
</executions>
</configuration>
</plugins>
</plugins>
其中需要注意的是<excludeGroupIds>需要添加不被打包的依賴項,複製mvn dependency:tree的運行結果即可。這樣打包後我們該如何部署呢?
我們新建一個文件夾叫做mini-deploy,把第三方依賴放在commLibs下,把工程jar包放在appLibs下,新建一個conf文件夾放配置文件,新建一個bin文件夾存放運行腳本。把resources下的所有內容放在conf下面。
在bin下新建一個run.bat
title "SpringBoot Application"
cd ..
java -Dloader.path="commonLibs/" -jar appLib/demo-0.0.1.jar --spring.config.location=file:conf/application.properties
pause
注意,要根據自己工程的實際情況修改工程名和配置文件名,還要將配置文件中的classpath:修改爲conf/