1. 程式人生 > >SpringBoot之整合其它熱門技術詳細總結

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多環境配置

  1. 配置啟用選項

spring.profiles.active=dev ### 代表使用開發環境

2.新增其他配置檔案

img

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"