SpringBoot之整合其它熱門技術詳細總結
開心一笑
【坐在沙發上看電視,女友洗完澡出來蠻開心的問我,親愛的:為什麼洗完澡總覺得自己漂亮了好多?我問她:你洗澡的時候洗了頭吧?她說:是啊!我回答說:那肯定是腦子進水了…剛說完這句我就後悔了,看著女票的臉色,我想靜靜…】
提出問題
SpringBoot整合其它技術大合集???
學習地址
解決問題
前言
本篇文章是《一步一步學SpringBoot(二)》教學視訊的簡單課件,內容不是很詳細,想了解全部內容,可以到上面的視訊地址觀看學習。
Spring Boot攔截器Interceptor
1)Spring boot攔截器預設
- HandlerInterceptorAdapter
- AbstractHandlerMapping
- UserRoleAuthorizationInterceptor
- LocaleChangeInterceptor
- ThemeChangeInterceptor
preHandle****:**預處理回撥方法,實現處理器的預處理(如登入檢查),第三個引數為響應的處理器(如我們上一章的Controller實現);
返回值:true表示繼續流程(如呼叫下一個攔截器或處理器);
false表示流程中斷(如登入檢查失敗),不會繼續呼叫其他的攔截器或處理器,此時我們需要通過response來產生響應;
postHandle****:**後處理回撥方法,實現處理器的後處理(但在渲染檢視之前),此時我們可以通過modelAndView(模型和檢視物件)對模型資料進行處理或對檢視進行處理,modelAndView也可能為null。
afterCompletion****:整個請求處理完畢回撥方法,即在檢視渲染完畢時回撥,如效能監控中我們可以在此記錄結束時間並輸出消耗時間,還可以進行一些資源清理,類似於try-catch-finally中的finally,但僅呼叫處理器執行鏈中preHandle返回true的攔截器的afterCompletion。
2)配置spring mvc的攔截器WebMvcConfigurerAdapter
public class WebAppConfig extends WebMvcConfigurerAdapter
具體類如下:
package com.example.interceptor.test;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Created by Ay on 2017/8/23.
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserSecurityInterceptor()).addPathPatterns("/springdata/*");
}
}
3)實現新增攔截器方法
public void addInterceptors(InterceptorRegistry registry){
}
registry.addInterceptor可以通過此方法新增攔截器, 可以是spring提供的或者自己新增的
具體類如下:
package com.example.interceptor.test;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Created by Ay on 2017/8/23.
*/
public class UserSecurityInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
//業務處理
System.out.println("preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//業務處理
System.out.println("postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex)throws Exception {
//業務處理
System.out.println("afterCompletion");
}
}
4)定義控制層進行測試
具體類如下:
package com.example.interceptor.test;
import io.swagger.annotations.ApiOperation;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Ay
* @date 2017/1/24.
*/
@RestController
@RequestMapping(value="/springdata")
@EnableAutoConfiguration
@EnableScheduling
public class AyInterceptorsTestController {
@RequestMapping("/ay")
@ApiOperation(value = "ay",httpMethod ="GET", response = String.class,notes = "index")
public String index(){
return "Hello Ay...";
}
@RequestMapping("/test")
@ApiOperation(value = "test",httpMethod ="GET", response = String.class,notes = "index")
public String test(){
return "Hello Ay...";
}
}
Spring Boot整合MongoDB
假如你已經安裝好了mongoDB資料庫,並新建了一個test資料庫。那麼開始吧
1)pom檔案新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2)建立實體
package com.example.mongodb.test;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.persistence.Id;
/**
* 描述:
* @author Ay
* @date 2017/08/22
*/
@Document
public class AyTest {
@Id
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3)服務層
package com.example.mongodb.test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* Created by Ay on 2017/8/23.
*/
@Component
public class UserDaoImpl {
@Autowired
private MongoTemplate mongoTemplate;
public void save(){
AyTest ayTest = new AyTest();
ayTest.setId("2");
ayTest.setName("al");
mongoTemplate.save(ayTest);
}
}
4)application.properties新增配置
###mongodb
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=test
5)測試
package com.example.mongodb.test;
import com.example.intellij.test.AyTest;
import com.example.intellij.test.AyTestService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Ay on 2017/1/24.
*/
@RestController
@RequestMapping("/mongo")
public class MongoDBTestController {
@Autowired
private UserDaoImpl userDaoImpl;
@RequestMapping("/al")
public String index2(){
userDaoImpl.save();
return "Hello Ay...";
}
}
Spring Boot多環境配置
一. 多環境配置的好處:
1.不同環境配置可以配置不同的引數~
2.便於部署,提高效率,減少出錯~
二. properties多環境配置
配置啟用選項
spring.profiles.active=dev ### 代表使用開發環境
2.新增其他配置檔案
application.properties:
#啟用哪一個環境的配置檔案
spring.profiles.active=dev
Spring Boot整合Log4J
1)新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排查預設日誌包 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入log4j2依賴 start-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- 引入log4j2依賴 end-->
2)application.properties新增
logging.config=classpath:log4j2.xml
3)resources資料夾下新增檔案 log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
4)測試下
package com.example.log4j2.test;
import com.example.intellij.test.AyTestService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Ay on 2017/1/24.
*/
@RestController
@RequestMapping("/log4j2")
public class Log4JTestController {
@Autowired
private AyTestService ayTestService;
Logger logger = LogManager.getLogger(this.getClass());
@RequestMapping("/al")
public String index2(){
logger.info("method start");
logger.equals("method start");
return "Hello Ay...";
}
}
Spring Boot事務控制
在Spring Boot中,當我們使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依賴的時候,框 架會自動預設分別注入DataSourceTransactionManager或JpaTransactionManager。所以我們不需要任何額外 配置就可以用@Transactional註解進行事務的使用。
1)主要是@Transactional這個註解的使用
package com.example.transaction.test;
import com.example.intellij.test.AyTest;
import com.example.intellij.test.AyTestService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by Ay on 2017/1/24.
*/
@RestController
@RequestMapping("/transaction")
public class TransactionTestController {
@Autowired
private AyTestService ayTestService;
@RequestMapping("/ay")
@Transactional
public String index() {
AyTest ayTest = new AyTest();
ayTest.setId("1");
ayTest.setName("ay");
AyTest ayTest2 = new AyTest();
ayTest2.setId("2");
ayTest2.setName("al & ay");
AyTest ayTest3 = new AyTest();
ayTest3.setId("3");
ayTest3.setName("al");
ayTestService.insert(ayTest);
ayTestService.insert(ayTest2);
//這邊出現異常
String s = null;
s.split(",");
ayTestService.insert(ayTest3);
return "Hello Ay...";
}
}
Spring Boot自定義錯誤頁面
1)在resources/static資料夾下新建3個檔案:401.html,404.html,500.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
我是一個漂亮的401
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
我是一個漂亮的404
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
我是一個漂亮的500
</body>
</html>
2)開發配置類
package com.example.errorpage.test;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.ErrorPage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
/**
* Created by Ay on 2017/8/23.
*/
@Configuration
public class ErrorPageConfig {
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return new EmbeddedServletContainerCustomizer() {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
ErrorPage error401Page = new ErrorPage(HttpStatus.UNAUTHORIZED, "/401.html");
ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/404.html");
ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/500.html");
container.addErrorPages(error401Page, error404Page, error500Page);
}
};
}
}
Spring Boot運用打包釋出
略,可看我錄製的《一步一步學SpringBoot(二)》教學視訊
Spring Boot使用Druid
Druid是Java語言中最好的資料庫連線池,並且能夠提供強大的監控和擴充套件功能。
第一步:新增依賴
<!-- druid start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
<!-- druid end -->
第二步:配置資料來源相關資訊
#mysql配置資訊
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test2
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 下面為連線池的補充設定,應用到上面所有資料來源中
# 初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置獲取連線等待超時的時間
spring.datasource.maxWait=60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一個連線在池中最小生存的時間,單位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 開啟PSCache,並且指定每個連線上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置監控統計攔截的filters,去掉後監控介面sql無法統計,'wall'用於防火牆
spring.datasource.filters=stat,wall,log4j
# 通過connectProperties屬性來開啟mergeSql功能;慢SQL記錄
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合併多個DruidDataSource的監控資料
#spring.datasource.useGlobalDataSourceStat=true
第三步:配置監控統計功能
package com.example.druid.test;
import com.alibaba.druid.support.http.WebStatFilter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
/**
* druid過濾器.
* @author Administrator
*
*/
@WebFilter(filterName="druidWebStatFilter",urlPatterns="/*",
initParams={
@WebInitParam(name="exclusions",value="*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// 忽略資源
}
)
public class DruidStatFilter extends WebStatFilter {
}
package com.example.druid.test;
import com.alibaba.druid.support.http.StatViewServlet;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
/**
* druid資料來源狀態監控.
* @author Administrator
*
*/
@WebServlet(urlPatterns="/druid/*",
initParams={
@WebInitParam(name="allow",value="192.168.1.72,127.0.0.1"),// IP白名單 (沒有配置或者為空,則允許所有訪問)
@WebInitParam(name="deny",value="192.168.1.73"),// IP黑名單 (存在共同時,deny優先於allow)
@WebInitParam(name="loginUsername",value="admin"),// 使用者名稱
@WebInitParam(name="loginPassword",value="123456"),// 密碼
@WebInitParam(name="resetEnable",value="false")// 禁用HTML頁面上的“Reset All”功能
}
)
public class DruidStatViewServlet extends StatViewServlet {
private static final long serialVersionUID = 1L;
}
Spring Boot 使用Retry重試
1)引入pom檔案
<!-- spring-retry start -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<!-- spring-retry start -->
2)自定義一個簡單異常
package com.example.retry.test;
/**
* Created by Ay on 2017/8/22.
*/
public class BusinessException extends Exception{
}
3)服務類
package com.example.retry.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
@Component("remoteService")
public class RemoteService {
private static final Logger logger = LoggerFactory.getLogger(RemoteService.class);
@Retryable(value= {BusinessException.class},maxAttempts = 5,backoff = @Backoff(delay = 5000,multiplier = 2))
public void call() throws Exception {
logger.info("do something...");
throw new BusinessException();
}
@Recover
public void recover(BusinessException e) {
//具體的業務邏輯
logger.info(" --------------------------- ");
logger.info(e.getMessage());
}
}
4)測試類
package com.example.retry.test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/retry")
public class TestController {
private static final Logger logger = LoggerFactory.getLogger(TestController.class);
@Autowired
private RemoteService remoteService;
@RequestMapping("/test")
public String login() throws Exception {
remoteService.call();
return String.valueOf("11");
}
}
Spring Boot 整合 Spring Data
1)新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2)新建model和資料庫表
package com.example.springdata.test;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
* 描述:
* @author Ay
* @date 2017/08/22
*/
@Entity
public class AyTest {
@Id
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3)新建UserRepository
package com.example.springdata.test;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
* @author Ay
* @date 2017/08/22
*/
public interface UserRepository extends CrudRepository<AyTest, String> {
List<AyTest> findByIdAndName(String id, String name);
}
4)測試類
package com.example.springdata.test;
import com.example.intellij.test.Ay;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.UUID;
/**
* Created by Ay on 2017/1/24.
*/
@RestController
@RequestMapping("/springdata")
public class SpringDataController {
@Autowired
private UserRepository userRepository;
@RequestMapping("/test")
public String index() {
AyTest ayTest = new AyTest();
ayTest.setId("60");
ayTest.setName("ay and al");
//select * from ay_test where id = '60' and name = "al"
List<AyTest> ayTestList = userRepository.findByIdAndName("60","ay and al");
return "Hello Ay...";
}
}
Spring Boot整合Websocket
第一步:引入pom檔案
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
第二步:使用@ServerEndpoint創立websocket endpoint
首先要注入ServerEndpointExporter,這個bean會自動註冊使用了@ServerEndpoint註解宣告的Websocket endpoint。要注意,如果使用獨立的servlet容器,而不是直接使用springboot的內建容器,就不要注入ServerEndpointExporter,因為它將由容器自己提供和管理。
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
第三步:
@ServerEndpoint(value = "/websocket")
@Component
public class MyWebSocket {
//靜態變數,用來記錄當前線上連線數。應該把它設計成執行緒安全的。
private static int onlineCount = 0;
//concurrent包的執行緒安全Set,用來存放每個客戶端對應的MyWebSocket物件。
private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
//與某個客戶端的連線會話,需要通過它來給客戶端傳送資料
private Session session;
/**
* 連線建立成功呼叫的方法*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
webSocketSet.add(this); //加入set中
addOnlineCount(); //線上數加1
System.out.println("有新連線加入!當前線上人數為" + getOnlineCount());
try {
sendMessage(CommonConstant.CURRENT_WANGING_NUMBER.toString());
} catch (IOException e) {
System.out.println("IO異常");
}
}
/**
* 連線關閉呼叫的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this); //從set中刪除
subOnlineCount(); //線上數減1
System.out.println("有一連線關閉!當前線上人數為" + getOnlineCount());
}
/**
* 收到客戶端訊息後呼叫的方法
*
* @param message 客戶端傳送過來的訊息*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("來自客戶端的訊息:" + message);
//群發訊息
for (MyWebSocket item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 發生錯誤時呼叫
@OnError
public void onError(Session session, Throwable error) {
System.out.println("發生錯誤");
error.printStackTrace();
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}
/**
* 群發自定義訊息
* */
public static void sendInfo(String message) throws IOException {
for (MyWebSocket item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
continue;
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
MyWebSocket.onlineCount++;
}
public static synchronized void subOnlineCount() {
MyWebSocket.onlineCount--;
}
}
第四步:
<!DOCTYPE HTML>
<html>
<head>
<title>My WebSocket</title>
</head>
<body>
Welcome<br/>
<input id="text" type="text"