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

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

新聞中心

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

1、本篇前言

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

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

(1)Starter的概念

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

(2)Starter的優(yōu)點(diǎn)

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

(3)自定義Starter的場(chǎng)景

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

常見(jiàn)的自定義Starter場(chǎng)景比如:

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

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

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

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

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

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

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

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

(2)log-spring-boot-starter項(xiàng)目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)編寫(xiě)請(qǐng)求日志注解

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

(4)編寫(xiě)配置類(lèi)

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

private Boolean enabled = Boolean.FALSE;
}

(5)編寫(xiě)日志攔截器

/**
* 功能描述: 日志攔截器
* @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("請(qǐng)求路徑:{},請(qǐng)求方法:{},描述信息:{},總計(jì)耗時(shí):{}",requestUri,methodName,desc,l);
}
}
}

(6)編寫(xiě)自動(dòng)配置類(lèi)

/**
* 功能描述: 自動(dòng)配置
* @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)編寫(xiě)spring.factories

在resources/META-INF/下建立spring.factories文件,配置自動(dòng)裝配類(lèi)路徑

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)編寫(xiě)測(cè)試接口并使用starter中定義的注解

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

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

(10)配置文件

server:
port: 8080
# 開(kāi)啟starter組件
request:
log:
enabled: true

(11)功能測(cè)試

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

(12)演示工程代碼

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

3、原理解析

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

(1)配置類(lèi)自動(dòng)加載機(jī)制

在SpringBoot的啟動(dòng)類(lèi)都會(huì)加上@SpringBootApplication注解。這個(gè)注解會(huì)引入@EnableAutoConfiguration注解。然后@EnableAutoConfiguration會(huì)@Import(AutoConfigurationImportSelector.class)。

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

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

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

@Conditional*注解

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

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

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

@ConfigurationProperties注解

這個(gè)注解主要是為了解決如下場(chǎng)景:我想要使用starter的默認(rèn)配置類(lèi),但是又想對(duì)配置中的某些參數(shù)進(jìn)行自定義配置。@ConfigurationProperties類(lèi)就是做這個(gè)工作的。例如上述例子中,我們?cè)谂渲弥惺褂胑nabled參數(shù)來(lái)決定是否啟動(dòng)該組件的日志攔截功能。


網(wǎng)頁(yè)名稱:進(jìn)階篇-SpringBoot2.x自定義starter啟動(dòng)器
URL分享:http://m.5511xx.com/article/ccchsdj.html