1. 程式人生 > >SpringBoot 2.0入門(4)

SpringBoot 2.0入門(4)

熱部署

1.什麼是熱部署
所謂的熱部署:比如專案的熱部署,就是在應用程式在不停止的情況下,實現新的部署

2.專案演示案例

@RestController
@Slf4j
public class IndexController {
	@Value("${itma}")
	private String itma;

	@RequestMapping("/index")
	public String index() {
		String result = "springboot2.0 V1.0";
		log.info("result:{}", result);
		return result + itma;
	}

}

3.熱部署原理
spring-boot-devtools 是一個為開發者服務的一個模組,其中最重要的功能就是自動應用程式碼更改到最新的App上面去。原理是在發現程式碼有更改之後,重新啟動應用,但是速度比手動停止後再啟動還要更快,更快指的不是節省出來的手工操作的時間。
其深層原理是使用了兩個ClassLoader,一個Classloader載入那些不會改變的類(第三方Jar包),另一個ClassLoader載入會更改的類,稱為 restart ClassLoader
,這樣在有程式碼更改的時候,原來的restart ClassLoader 被丟棄,重新建立一個restart ClassLoader,由於需要載入的類相比較少,所以實現了較快的重啟時間(5秒以內)

4.Devtools依賴

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

5.Devtools原理

  1. devtools會監聽classpath下的檔案變動,並且會立即重啟應用(發生在儲存時機),注意:因為其採用的虛擬機器機制,該項重啟是很快的。
  2. devtools可以實現頁面熱部署(即頁面修改後會立即生效,這個可以直接在application.properties檔案中配置spring.thymeleaf.cache=false來實現(這裡注意不同的模板配置不一樣)

監控管理

Actuator監控應用
Actuator是spring boot的一個附加功能,可幫助你在應用程式生產環境時監視和管理應用程式。可以使用HTTP的各種請求來監管,審計,收集應用的執行情況.特別對於微服務管理十分有意義.缺點:沒有視覺化介面。

Maven依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

	</dependencies>

YML配置

###通過下面的配置啟用所有的監控端點,預設情況下,這些端點是禁用的;
management:
  endpoints:
    web:
      exposure:
        include: "*"
spring:
  profiles:
    active: prod
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test
    username: root
    password: root
itma: 
   name: itma


Actuator訪問路徑
通過actuator/+端點名就可以獲取相應的資訊。

路徑 作用
/actuator/beans 顯示應用程式中所有Spring bean的完整列表。
/actuator/configprops 顯示所有配置資訊。
/actuator/env 陳列所有的環境變數。
/actuator/mappings 顯示所有@RequestMapping的url整理列表。
/actuator/health 顯示應用程式執行狀況資訊 up表示成功 down失敗
/actuator/info 檢視應用資訊

演示案例:
/actuator/info 配置檔案新增

info:
  itma: itma
  addres: www.itma.com

Admin-UI分散式微服務監控中心
Admin-UI基於actuator實現能夠返回介面展示監控資訊

Admin-UI-Server
Maven依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>de.codecentric</groupId>
			<artifactId>spring-boot-admin-starter-server</artifactId>
			<version>2.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-webflux</artifactId>
		</dependency>
		<!-- Spring Boot Actuator對外暴露應用的監控資訊,Jolokia提供使用HTTP介面獲取JSON格式 的資料 -->
		<dependency>
			<groupId>org.jolokia</groupId>
			<artifactId>jolokia-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>com.googlecode.json-simple</groupId>
			<artifactId>json-simple</artifactId>
			<version>1.1</version>
		</dependency>
	</dependencies>

application.yml配置檔案

spring:
  application:
    name: spring-boot-admin-server

啟動方式

@Configuration
@EnableAutoConfiguration
@EnableAdminServer
public class AdminServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(AdminServerApplication.class, args);
	}
}

Admin-UI-Client
Maven依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>de.codecentric</groupId>
			<artifactId>spring-boot-admin-starter-client</artifactId>
			<version>2.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.jolokia</groupId>
			<artifactId>jolokia-core</artifactId>
		</dependency>
		<dependency>
			<groupId>com.googlecode.json-simple</groupId>
			<artifactId>json-simple</artifactId>
			<version>1.1</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>


	</dependencies>

YML配置

spring:
  boot:
    admin:
      client:
        url: http://localhost:8080
server:
  port: 8081
  
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS

啟動類

@SpringBootApplication
public class AppClinet {

	public static void main(String[] args) {
		SpringApplication.run(AppClinet.class, args);
	}

}

效能優化

1.元件自動掃描帶來的問題
預設情況下,我們會使用 @SpringBootApplication 註解來自動獲取應用的配置資訊,但這樣也會給應用帶來一些副作用。使用這個註解後,會觸發自動配置( auto-configuration )和 元件掃描 ( component scanning ),這跟使用 @Configuration、@EnableAutoConfiguration 和 @ComponentScan 三個註解的作用是一樣的。這樣做給開發帶來方便的同時,也會有三方面的影響:
1、會導致專案啟動時間變長。當啟動一個大的應用程式,或將做大量的整合測試啟動應用程式時,影響會特別明顯。
2、會載入一些不需要的多餘的例項(beans)。
3、會增加 CPU 消耗。
針對以上三個情況,我們可以移除 @SpringBootApplication 和 @ComponentScan 兩個註解來禁用元件自動掃描,然後在我們需要的 bean 上進行顯式配置:

//// 移除 @SpringBootApplication and @ComponentScan, 用 @EnableAutoConfiguration 來替代
//@SpringBootApplication
@Configuration
@EnableAutoConfiguration
public class App01 {

	public static void main(String[] args) {
		SpringApplication.run(App01.class, args);
	}

}

以@SpringBootApplication 啟動時間8.56秒

將Servlet容器變成Undertow
預設情況下,Spring Boot 使用 Tomcat 來作為內嵌的 Servlet 容器
可以將 Web 伺服器切換到 Undertow 來提高應用效能。Undertow 是一個採用 Java 開發的靈活的高效能 Web 伺服器,提供包括阻塞和基於 NIO 的非堵塞機制。Undertow 是紅帽公司的開源產品,是 Wildfly 預設的 Web 伺服器。首先,從依賴資訊裡移除 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>

然後新增 Undertow:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>

SpringBoot JVM引數調優

這個根據伺服器的記憶體大小,來設定堆引數。
-Xms :設定Java堆疊的初始化大小
-Xmx :設定最大的java堆大小
例項引數-XX:+PrintGCDetails -Xmx32M -Xms1M
本地專案調優

在這裡插入圖片描述

外部執行調優
java -server -Xms32m -Xmx32m -jar springboot_v2.jar

伺服器名稱 第一次執行 第二次執行 第三次執行 平均值
Tomcat 4773 5194 5334.7 5100
Undertow 6666 6373 6451 6496

2.0版本新特性

以Java 8 為基準
Spring Boot 2.0 要求Java 版本必須8以上, Java 6 和 7 不再支援。

內嵌容器包結構調整
為了支援reactive使用場景,內嵌的容器包結構被重構了的幅度有點大。EmbeddedServletContainer被重新命名為WebServer,並且org.springframework.boot.context.embedded 包被重定向到了org.springframework.boot.web.embedded包下。舉個例子,如果你要使用TomcatEmbeddedServletContainerFactory回撥介面來自定義內嵌Tomcat容器,你現在應該使用TomcatServletWebServerFactory。

Servlet-specific 的server properties調整
大量的Servlet專屬的server.* properties被移到了server.servlet下:

Old property New property
server.context-parameters.* server.servlet.context-parameters.*
server.context-path server.servlet.context-path
server.jsp.class-name server.servlet.jsp.class-name
server.jsp.init-parameters.* server.servlet.jsp.init-parameters.*
server.jsp.registered server.servlet.jsp.registered
server.servlet-path server.servlet.path

其他內容

1.使用@Scheduled建立定時任務
在Spring Boot的主類中加入@EnableScheduling註解,啟用定時任務的配置

@Component
public class ScheduledTasks {
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        System.out.println("現在時間:" + dateFormat.format(new Date()));
    }
}

2.使用@Async實現非同步呼叫
啟動加上@EnableAsync ,需要執行非同步方法上加入 @Async
在方法上加上@Async之後 底層使用多執行緒技術

2.1 Maven依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	</dependencies>

2.2 演示程式碼

@RestController
@Slf4j
public class IndexController {

	@Autowired
	private UserService userService;

	@RequestMapping("/index")
	public String index() {
		log.info("##01##");
		userService.userThread();
		log.info("##04##");
		return "success";
	}

}

@Service
@Slf4j
public class UserService {

	@Async // 類似與開啟執行緒執行..
	public void userThread() {
		log.info("##02##");
		try {
			Thread.sleep(5 * 1000);
		} catch (Exception e) {
			// TODO: handle exception
		}
		log.info("##03##");

		// new Thread(new Runnable() {
		// public void run() {
		// log.info("##02##");
		// try {
		// Thread.sleep(5 * 1000);
		// } catch (Exception e) {
		// // TODO: handle exception
		// }
		// log.info("##03##");
		// }
		// }).start();
	}

}


@EnableAsync // 開啟非同步註解
@SpringBootApplication
public class App {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}

3.自定義引數
配置檔案值

name=itma

配置檔案值

@Value("${name}")
	private String name;
@ResponseBody
	@RequestMapping("/getValue")
	public String getValue() {
		return name;
	}

4.多環境配置

spring.profiles.active=pre
application-dev.properties:開發環境
application-test.properties:測試環境
application-prod.properties:生產環境

5.修改埠號

server.port=8888 
server.context-path=/itma

6.SpringBoot yml 使用
建立application.yml

server:
  port:  8090
  context-path: /itma

7.釋出打包
使用mvn package 打包
使用java –jar 包名
如果報錯沒有主清單,在pom檔案中新增

<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<maimClass>com.itmayiedu.app.App</maimClass>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>

			</plugin>
		</plugins>
	</build>

8.SpringBoot整合攔截器
攔截器
建立攔截器
建立模擬登入攔截器,驗證請求是否有token引數

Slf4j
@Component
public class LoginIntercept implements HandlerInterceptor {

	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		log.info("開始攔截登入請求....");
		String token = request.getParameter("token");
		if (StringUtils.isEmpty(token)) {
			response.getWriter().println("not found token");
			return false;
		}
		return true;
	}

}

註冊攔截器

@Configuration
public class WebAppConfig {
	@Autowired
	private LoginIntercept loginIntercept;

	@Bean
	public WebMvcConfigurer WebMvcConfigurer() {
		return new WebMvcConfigurer() {
			public void addInterceptors(InterceptorRegistry registry) {
				registry.addInterceptor(loginIntercept).addPathPatterns("/*");
			};
		};
	}

}

截器與過濾器區別
攔截器是AOP( Aspect-Oriented Programming)的一種實現,底層通過動態代理模式完成。
(1)攔截器是基於java的反射機制的,而過濾器是基於函式回撥。
(2)攔截器不依賴於servlet容器,而過濾器依賴於servlet容器。
(3)攔截器只能對Controller請求起作用,而過濾器則可以對幾乎所有的請求起作用。
(4)在Controller的生命週期中,攔截器可以多次被呼叫,而過濾器只能在容器初始化時被呼叫一次。

過濾器應用場景:設定編碼字元、過濾銘感字元
攔截器應用場景:攔截未登陸使用者、審計日誌()

釋出打包

Jar型別打包方式
1.使用mvn celan package 打包
2.使用java –jar 包名

war型別打包方式
1.使用mvn celan package 打包
2.使用java –jar 包名

外部Tomcat執行
1.使用mvn celan package 打包
2.2.0將war包 放入到tomcat webapps下執行即可。

注意:springboot2.0內建tomcat8.5.25,建議使用外部Tomcat9.0版本執行即可,否則報錯版本不相容。

打包常見錯誤
如果報錯沒有主清單,在pom檔案中新增

<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<maimClass>com.itmayiedu.app.App</maimClass>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>

			</plugin>
		</plugins>
	</build>

Java jar 執行的時候報錯 ’ 不是內部或外部命令 說明 jdk環境沒有安裝