日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
進階篇-SpringBoot2.x自定義starter啟動器

1、本篇前言

Spring Boot為我們提供了簡化企業(yè)級開發(fā)絕大多數(shù)場景的
starter pom【比如springb-boot-starter-web,springb-boot-starter-jdbc等】, 使用應用場景所需要的starter pom,只需要引入對應的starter,即可以得到Spring Boot為我們提供的自動配置的Bean。
然而,可能在很多情況下,我們需要自定義stater,這樣可以方便公司內(nèi)部系統(tǒng)調(diào)用共同的配置模塊的時候可以自動進行裝載配置。比如公司的很多內(nèi)部系統(tǒng)都有認證授權(quán)模塊、以及基于AOP實現(xiàn)的日志切面等,這些技術(shù)在不同的項目中邏輯基本相同,而這些功能可以通過starter自動配置的形式進行配置,即可達到可復用的效果。

專注于為中小企業(yè)提供網(wǎng)站制作、成都做網(wǎng)站服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)良慶免費做網(wǎng)站提供優(yōu)質(zhì)的服務。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。

(1)Starter的概念

SpringBoot之所以大大地簡化了我們的開發(fā),用到的一個很重要的技術(shù)就是Starter機制!
Starter機制拋棄了以前xml中繁雜的配置,將各種配置統(tǒng)一集成進了Starter中,開發(fā)人員只需要在maven中引入Starter依賴,SpringBoot就能自動掃描出要加載的配置信息并按相應的默認配置來啟動項目。
所以Starter可以理解為一個可拔插式的插件,提供了一系列便利的依賴描述符,使得我們可以獲得所需的所有Spring和相關(guān)技術(shù)的一站式服務。應用程序只需要在maven中引入Starter依賴,SpringBoot就能自動掃描到要加載的信息并啟動相應的默認配置,我們可以把Starter看做是Springboot的場景啟動器。

(2)Starter的優(yōu)點

  • Starter可以讓我們擺脫開發(fā)過程中對各種依賴庫的沖突處理。
  • 可以簡化原有xml中各種負載的配置信息。
  • SpringBoot提供了針對一般研發(fā)中各種場景的spring-boot-starter依賴,所有這些依賴模塊都遵循著約定成俗的默認配置(”約定大于配置“),并允許我們調(diào)整這些配置。Starter的出現(xiàn)極大的幫助開發(fā)者們從繁瑣的框架配置中解放出來,從而更專注于業(yè)務代碼。

(3)自定義Starter的場景

在我們的日常開發(fā)工作中,經(jīng)常會有一些獨立于業(yè)務之外的配置模塊,我們經(jīng)常將其放到一個特定的包下,然后如果另一個工程需要復用這塊功能的時候,只需要將其在pom中引用依賴即可,利用SpringBoot為我們完成自動裝配即可。

常見的自定義Starter場景比如:

  • 動態(tài)數(shù)據(jù)源
  • 登錄模塊
  • 基于AOP技術(shù)實現(xiàn)日志切面

(4)自定義Starter命名規(guī)范

SpringBoot官方建議其官方推出的starter以spring-boot-starter-xxx的格式來命名,而第三方開發(fā)者自定義的starter則以xxxx-spring-boot-starter的規(guī)則來命名,比如 mybatis-spring-boot-starter。

(5)自定義starter中幾個重要注解

  • @Configuration: 表明此類是一個配置類,將變?yōu)橐粋€bean被Spring進行管理。
  • @EnableConfigurationProperties: 啟用屬性配置,將讀取指定類里面的屬性。
  • @ConditionalOnClass: 當類路徑下面有指定的類時,進行自動配置。
  • @ConditionalOnProperty: 判斷指定的屬性是否具備指定的值。
  • @ConditionalOnMissingBean:當容器中沒有指定bean是,創(chuàng)建此bean。
  • @Import: 引入其他的配置類

2、自定義Starter記錄日志案例

(1)項目結(jié)構(gòu)

兩個工程如下:log-spring-boot-starter[starter模塊],spring-boot-demo-starter-test[starter使用演示工程]。

(2)log-spring-boot-starter項目pom文件添加依賴



org.springframework.boot
spring-boot-starter


org.springframework.boot
spring-boot-configuration-processor
true


org.springframework.boot
spring-boot-starter-web


org.projectlombok
lombok
true


org.springframework.boot
spring-boot-starter-test
test

(3)編寫請求日志注解

/**
* 功能描述: 請求日志注解
* @author TuYong
* @date 2022/9/7 20:48
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestLog {
//接口方法上的描述信息
String desc() default "";
}

(4)編寫配置類

@Setter
@Getter
@ConfigurationProperties(prefix = "request.log")
public class LogProperties {

private Boolean enabled = Boolean.FALSE;
}

(5)編寫日志攔截器

/**
* 功能描述: 日志攔截器
* @author TuYong
* @date 2022/9/7 20:49
*/
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
private static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>();

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
RequestLog methodAnnotation = handlerMethod.getMethodAnnotation(RequestLog.class);
if(methodAnnotation != null){
long start = System.currentTimeMillis();
THREAD_LOCAL.set(start);
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
RequestLog methodAnnotation = handlerMethod.getMethodAnnotation(RequestLog.class);
if(methodAnnotation != null){
Method method = handlerMethod.getMethod();
String requestUri = request.getRequestURI();
String methodName = method.getDeclaringClass().getName()+":"+method.getName();
String desc = methodAnnotation.desc();
long end = System.currentTimeMillis();
long start = THREAD_LOCAL.get();
long l = end - start;
THREAD_LOCAL.remove();
log.info("請求路徑:{},請求方法:{},描述信息:{},總計耗時:{}",requestUri,methodName,desc,l);
}
}
}

(6)編寫自動配置類

/**
* 功能描述: 自動配置
* @author TuYong
* @date 2022/9/7 20:55
*/
@Configuration
@EnableConfigurationProperties({LogProperties.class})
@ConditionalOnProperty(
prefix = "request.log",
name = {"enabled"},
havingValue = "true"
)
public class LogAutoConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor()).addPathPatterns("/api/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}

(7)編寫spring.factories

在resources/META-INF/下建立spring.factories文件,配置自動裝配類路徑

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.javaxxw.springboot.LogAutoConfiguration

(8)創(chuàng)建starter演示工程引入starter依賴



cn.javaxxw
log-spring-boot-starter
0.0.1-SNAPSHOT



org.springframework.boot
spring-boot-starter-web

(9)編寫測試接口并使用starter中定義的注解

@RestController
@RequestMapping("api")
public class ApiController {

@GetMapping("test")
@RequestLog(desc = "測試接口")
public Object test(){
return "test api!";
}
}

(10)配置文件

server:
port: 8080
# 開啟starter組件
request:
log:
enabled: true

(11)功能測試

通過請求測試接口,我們可以看到starter中的攔截器已經(jīng)生效

(12)演示工程代碼

gitee: https://gitee.com/trazen/springboot-demo.git

3、原理解析

第二章節(jié)中的開發(fā)流程,有兩個地方需要我們了解一下:
(1)starter的自動識別加載:spring.factories里的EnableAutoConfiguration原理。
(2)實現(xiàn)自動加載的智能化、可配置化:@Configuration配置類里注解。

(1)配置類自動加載機制

在SpringBoot的啟動類都會加上@SpringBootApplication注解。這個注解會引入@EnableAutoConfiguration注解。然后@EnableAutoConfiguration會@Import(AutoConfigurationImportSelector.class)。

AutoConfigurationImportSelector.class的selectImports方法最終會通過SpringFactoriesLoader.loadFactoryNames,加載META-INF/spring.factories里的EnableAutoConfiguration配置值,也就是我們上文中設置的資源文件。

(2)自動加載的智能化可配置化

實際項目中,我們并不總是希望使用默認配置。比如有時候我想自己配置相關(guān)功能,或者只有某些bean沒有被加載時才會加載starter配置類。這些常見的場景Starter都可以實現(xiàn),并提供了如下的解決方案:

@Conditional*注解

springboot starter提供了一系列的@Conditional*注解,代表什么時候啟用對應的配置,具體的可以去查看springboot的官方文檔。常用注解如下:

  • @ConditionalOnBean:當容器里有指定的Bean的條件下。
  • @ConditionalOnClass: 當類路徑下面有指定的類時,進行自動配置。
  • @ConditionalOnProperty: 判斷指定的屬性是否具備指定的值。
  • @ConditionalOnMissingBean:當容器中沒有指定bean是,創(chuàng)建此bean。

比如我們案例中的 @ConditionalOnProperty(prefix = "request.log", name = {"enabled"},havingValue = "true") ,只有在應用配置 request.log.enabled = true 時該請求日志攔截功能才會生效。

@ConfigurationProperties注解

這個注解主要是為了解決如下場景:我想要使用starter的默認配置類,但是又想對配置中的某些參數(shù)進行自定義配置。@ConfigurationProperties類就是做這個工作的。例如上述例子中,我們在配置中使用enabled參數(shù)來決定是否啟動該組件的日志攔截功能。


文章標題:進階篇-SpringBoot2.x自定義starter啟動器
路徑分享:http://m.5511xx.com/article/ccchsdj.html