0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Spring中11個(gè)最常用的擴(kuò)展點(diǎn)分享1

jf_78858299 ? 來源:JAVA旭陽(yáng) ? 作者:JAVA旭陽(yáng) ? 2023-05-11 10:48 ? 次閱讀

前言

在使用spring的過程中,我們有沒有發(fā)現(xiàn)它的擴(kuò)展能力很強(qiáng)呢?由于這個(gè)優(yōu)勢(shì)的存在,使得spring具有很強(qiáng)的包容性,所以很多第三方應(yīng)用或者框架可以很容易的投入到spring的懷抱中。今天我們主要來學(xué)習(xí)Spring中很常用的11個(gè)擴(kuò)展點(diǎn),你用過幾個(gè)呢?

1. 類型轉(zhuǎn)換器

如果接口中接收參數(shù)的實(shí)體對(duì)象中,有一個(gè)字段類型為Date,但實(shí)際傳遞的參數(shù)是字符串類型:2022-12-15 10:20:15,該如何處理?

Spring提供了一個(gè)擴(kuò)展點(diǎn),類型轉(zhuǎn)換器Type Converter,具體分為3類:

  • Converter: 將類型 S 的對(duì)象轉(zhuǎn)換為類型 T 的對(duì)象
  • ConverterFactory: 將 S 類型對(duì)象轉(zhuǎn)換為 R 類型或其子類對(duì)象
  • GenericConverter:它支持多種源和目標(biāo)類型的轉(zhuǎn)換,還提供了源和目標(biāo)類型的上下文。此上下文允許您根據(jù)注釋或?qū)傩?a target="_blank">信息執(zhí)行類型轉(zhuǎn)換。

還是不明白的話,我們舉個(gè)例子吧。

  1. 定義一個(gè)用戶對(duì)象
@Data
public class User {
    private Long id;
    private String name;
    private Date registerDate;
}
  1. 實(shí)現(xiàn)Converter接口
public class DateConverter implements Converter
  1. 將新定義的類型轉(zhuǎn)換器注入到Spring容器中
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new DateConverter());
    }
}
  1. 調(diào)用接口測(cè)試
@RequestMapping("/user")
    @RestController
    public class UserController {
        @RequestMapping("/save")
        public String save(@RequestBody User user) {
            return "success";
        }
    }

請(qǐng)求接口時(shí),前端傳入的日期字符串,會(huì)自動(dòng)轉(zhuǎn)換成Date類型。

2. 獲取容器Bean

在我們?nèi)粘i_發(fā)中,經(jīng)常需要從Spring容器中獲取bean,但是你知道如何獲取Spring容器對(duì)象嗎?

2.1 BeanFactoryAware

@Service
public class PersonService implements BeanFactoryAware {
    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public void add() {
        Person person = (Person) beanFactory.getBean("person");
    }
}

實(shí)現(xiàn)BeanFactoryAware接口,然后重寫setBeanFactory方法,可以從方法中獲取spring容器對(duì)象。

2.2 ApplicationContextAware

@Service
public class PersonService2 implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void add() {
        Person person = (Person) applicationContext.getBean("person");
    }
}

實(shí)現(xiàn)ApplicationContextAware接口,然后重寫setApplicationContext方法,也可以通過該方法獲取spring容器對(duì)象。

2.3 ApplicationListener

@Service
public class PersonService3 implements ApplicationListener<ContextRefreshedEvent> {
    private ApplicationContext applicationContext;
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        applicationContext = event.getApplicationContext();
    }

    public void add() {
        Person person = (Person) applicationContext.getBean("person");
    }
}

3. 全局異常處理

以往我們?cè)陂_發(fā)界面的時(shí)候,如果出現(xiàn)異常,要給用戶更友好的提示,例如:

@RequestMapping("/test")
@RestController
public class TestController {

    @GetMapping("/add")
    public String add() {
        int a = 10 / 0;
        return "su";
    }
}

如果不對(duì)請(qǐng)求添加接口結(jié)果做任何處理,會(huì)直接報(bào)錯(cuò):

用戶可以直接看到錯(cuò)誤信息嗎?

這種交互給用戶帶來的體驗(yàn)非常差。為了解決這個(gè)問題,我們通常在接口中捕獲異常:

@GetMapping("/add")
public String add() {
    String result = "success";
    try {
        int a = 10 / 0;
    } catch (Exception e) {
        result = "error";
    }
    return result;
}

界面修改后,出現(xiàn)異常時(shí)會(huì)提示:“數(shù)據(jù)異?!?,更加人性化。

看起來不錯(cuò),但是有一個(gè)問題。

如果只是一個(gè)接口還好,但是如果項(xiàng)目中有成百上千個(gè)接口,還得加異常捕獲代碼嗎?

答案是否定的,這就是全局異常處理派上用場(chǎng)的地方:RestControllerAdvice。

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public String handleException(Exception e) {
        if (e instanceof ArithmeticException) {
            return "data error";
        }
        if (e instanceof Exception) {
            return "service error";
        }
        retur null;
    }
}

方法中處理異常只需要handleException,在業(yè)務(wù)接口中就可以安心使用,不再需要捕獲異常(統(tǒng)一有人處理)。

4. 自定義攔截器

Spring MVC攔截器,它可以獲得HttpServletRequestHttpServletResponse等web對(duì)象實(shí)例。

Spring MVC攔截器的頂層接口是HandlerInterceptor,它包含三個(gè)方法:

  • preHandle 在目標(biāo)方法執(zhí)行之前執(zhí)行
  • 執(zhí)行目標(biāo)方法后執(zhí)行的postHandle
  • afterCompletion 在請(qǐng)求完成時(shí)執(zhí)行

為了方便,我們一般繼承HandlerInterceptorAdapter,它實(shí)現(xiàn)了HandlerInterceptor。

如果有授權(quán)鑒權(quán)、日志、統(tǒng)計(jì)等場(chǎng)景,可以使用該攔截器,我們來演示下吧。

  1. 寫一個(gè)類繼承HandlerInterceptorAdapter
public class AuthInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception {
        String requestUrl = request.getRequestURI();
        if (checkAuth(requestUrl)) {
            return true;
        }
        return false;
    }
    private boolean checkAuth(String requestUrl) {
        return true;
    }
}
  1. 將攔截器注冊(cè)到spring容器中
@Configuration
public class WebAuthConfig extends WebMvcConfigurerAdapter {

    @Bean
    public AuthInterceptor getAuthInterceptor() {
        return new AuthInterceptor();
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new AuthInterceptor());
    }
}
  1. Spring MVC在請(qǐng)求接口時(shí)可以自動(dòng)攔截接口,并通過攔截器驗(yàn)證權(quán)限。

5. 導(dǎo)入配置

有時(shí)我們需要在某個(gè)配置類中引入其他的類,引入的類也加入到Spring容器中。這時(shí)候可以使用注解@Import來完成這個(gè)功能。

如果你查看它的源代碼,你會(huì)發(fā)現(xiàn)導(dǎo)入的類支持三種不同的類型。

但是我覺得最好把普通類的配置類和@Configuration注解分開解釋,所以列出了四種不同的類型:

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 轉(zhuǎn)換器
    +關(guān)注

    關(guān)注

    27

    文章

    8505

    瀏覽量

    145983
  • 框架
    +關(guān)注

    關(guān)注

    0

    文章

    396

    瀏覽量

    17269
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    335

    瀏覽量

    14259
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    什么是java spring

    的事情。然而,Spring的用途不僅限于服務(wù)器端的開發(fā)。從簡(jiǎn)單性、可測(cè)試性和松耦合的角度而言,任何Java應(yīng)用都可以從Spring受益。Spring是一
    發(fā)表于 09-11 11:16

    Spring工作原理

    Spring所提供的這些服務(wù)和功能。Spring里用的最經(jīng)典的一個(gè)設(shè)計(jì)模式就是:模板方法模式。(這里我都不介紹了,是一個(gè)常用的設(shè)計(jì)模式)
    發(fā)表于 07-10 07:41

    啟動(dòng)Spring Boot項(xiàng)目應(yīng)用的三種方法

    基礎(chǔ)。我們知道了Spring Boot是個(gè)什么了,那么我們又該如何啟動(dòng)Spring Boot應(yīng)用呢?這里小編給大家推薦常用的三種方法。分別是IDEA編輯器啟動(dòng)、命令啟動(dòng)、java命令j
    發(fā)表于 01-14 17:33

    STM32時(shí)鐘系統(tǒng)最常用的知識(shí)

    ,講一點(diǎn)最常用的知識(shí)。其它的型號(hào)大同小異。時(shí)鐘含義特點(diǎn)HSE外部高速時(shí)鐘信號(hào)一般選擇外接晶振,最常用的時(shí)鐘信號(hào)。電機(jī)驅(qū)動(dòng)板外接12MhzHSI內(nèi)部高速時(shí)鐘信號(hào)由單片...
    發(fā)表于 08-11 07:39

    高手最常用的電腦五個(gè)組合鍵

    高手最常用的電腦五個(gè)組合鍵 winkey+d : 這是高手最常用的第一快捷組合鍵。這個(gè)快捷鍵組合可以將桌面上的所有窗口瞬間最小化,無論是聊天的窗口還是
    發(fā)表于 02-24 10:41 ?61次下載

    Spring應(yīng)用 1 springXML配置說明

    Spring應(yīng)用 1 springXML配置說明 隱式對(duì)Spring容器注冊(cè)Process ? context:annotation-config / 為了在spring開發(fā)過程
    發(fā)表于 01-13 12:20 ?362次閱讀

    Spring認(rèn)證_什么是Spring GraphQL?

    數(shù)據(jù)整合 Spring GraphQL 支持使用 Querydsl 通過 Spring Data Querydsl 擴(kuò)展 來獲取數(shù)據(jù)。Querydsl 提供了一種靈活但類型安全的方法,通過使用注釋
    的頭像 發(fā)表于 08-09 11:31 ?532次閱讀
    <b class='flag-5'>Spring</b>認(rèn)證_什么是<b class='flag-5'>Spring</b> GraphQL?

    最常用11款Kubernetes工具

    助于改善 Kubernetes 開發(fā)人員的體驗(yàn)。本文列出作者自己最常用11 款 Kubernetes 工具,并對(duì)它們進(jìn)行了分類介紹。 Kubernetes 是一個(gè)非常強(qiáng)大的容器編排平臺(tái)。但在
    的頭像 發(fā)表于 08-23 10:43 ?2060次閱讀

    10個(gè)電源設(shè)計(jì)最常用公式的解析

    本文將為你解析10個(gè)電源設(shè)計(jì)最常用的公式。非常實(shí)用,推薦收藏哦~
    發(fā)表于 02-10 11:40 ?8次下載
    10<b class='flag-5'>個(gè)</b>電源設(shè)計(jì)<b class='flag-5'>最常用</b>公式的解析

    Spring最常用11個(gè)擴(kuò)展點(diǎn)

    除此之外,我們?cè)谑褂?b class='flag-5'>spring的過程,有沒有發(fā)現(xiàn)它的擴(kuò)展能力非常強(qiáng)。由于這個(gè)優(yōu)勢(shì)的存在,讓spring擁有強(qiáng)大的包容能力,讓很多第三方應(yīng)用能夠輕松投入
    的頭像 發(fā)表于 01-11 10:31 ?792次閱讀

    剖析Spring最常用擴(kuò)展點(diǎn)(上)

    我們一說到spring,可能第一個(gè)想到的是 `IOC`(控制反轉(zhuǎn)) 和 `AOP`(面向切面編程)。 沒錯(cuò),它們是spring的基石,得益于它們的優(yōu)秀設(shè)計(jì),使得spring能夠從
    的頭像 發(fā)表于 02-15 16:06 ?672次閱讀
    剖析<b class='flag-5'>Spring</b>中<b class='flag-5'>最常用</b>的<b class='flag-5'>擴(kuò)展</b><b class='flag-5'>點(diǎn)</b>(上)

    剖析Spring最常用擴(kuò)展點(diǎn)

    我們一說到spring,可能第一個(gè)想到的是 `IOC`(控制反轉(zhuǎn)) 和 `AOP`(面向切面編程)。 沒錯(cuò),它們是spring的基石,得益于它們的優(yōu)秀設(shè)計(jì),使得spring能夠從
    的頭像 發(fā)表于 02-15 16:06 ?435次閱讀
    剖析<b class='flag-5'>Spring</b>中<b class='flag-5'>最常用</b>的<b class='flag-5'>擴(kuò)展</b><b class='flag-5'>點(diǎn)</b>(<b class='flag-5'>中</b>)

    剖析Spring最常用擴(kuò)展點(diǎn)(下)

    我們一說到spring,可能第一個(gè)想到的是 `IOC`(控制反轉(zhuǎn)) 和 `AOP`(面向切面編程)。 沒錯(cuò),它們是spring的基石,得益于它們的優(yōu)秀設(shè)計(jì),使得spring能夠從
    的頭像 發(fā)表于 02-15 16:07 ?391次閱讀

    基于spring的SPI擴(kuò)展機(jī)制是如何實(shí)現(xiàn)的?

    基本上,你一說是基于 spring 的 SPI 擴(kuò)展機(jī)制,再把spring.factories文件和EnableAutoConfiguration提一下,那么這個(gè)問題就答的八九不離十了。
    的頭像 發(fā)表于 03-07 09:17 ?910次閱讀

    Spring11個(gè)最常用擴(kuò)展點(diǎn)分享2

    在使用spring的過程,我們有沒有發(fā)現(xiàn)它的擴(kuò)展能力很強(qiáng)呢?由于這個(gè)優(yōu)勢(shì)的存在,使得spring具有很強(qiáng)的包容性,所以很多第三方應(yīng)用或者框架可以很容易的投入到
    的頭像 發(fā)表于 05-11 10:48 ?325次閱讀