最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解決Hmily與Feign沖突報(bào)錯(cuò) NullPointerException的問(wèn)題

 更新時(shí)間:2021年11月16日 14:56:06   作者:Been_You  
這篇文章主要介紹了解決Hmily與Feign沖突報(bào)錯(cuò) NullPointerException的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Hmily與Feign沖突報(bào)錯(cuò) NullPointerException

在項(xiàng)目中使用了Hmily保證分布式事務(wù)的一致性,由于Hmily會(huì)注冊(cè)一個(gè) HmilyFeignInterceptor ,并且feign會(huì)將其添加到 SynchronousMethodHandler 中的 requestInterceptors ,當(dāng)feign客戶端執(zhí)行 HmilyFeignInterceptor 中apply方法

public void apply(final RequestTemplate requestTemplate) {
        Transmiter.getInstance().transmit((x$0, xva$1) -> {
            requestTemplate.header(x$0, new String[]{xva$1});
        }, HmilyTransactionContextLocal.getInstance().get());
    }

由于獲取到的 HmilyTransactionContext 為 null ,所以拋出 NullPointerException 異常。

解決方法

定義一個(gè)后置處理器,將沒(méi)有被 @Hmily 注解的方法,移除 HmilyFeignInterceptor 。

package com.jz.shop.cart.service;
import com.jz.shop.commons.utils.text.StringUtils;
import feign.InvocationHandlerFactory;
import feign.ReflectiveFeign;
import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hmily.annotation.Hmily;
import org.dromara.hmily.springcloud.feign.HmilyFeignInterceptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
/**
 * @author:JZ
 * @date:2020/6/1
 */
@Slf4j
@Component
public class ShopFeignPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 對(duì)所有含有 @FeignClient 的bean進(jìn)行處理
        if (StringUtils.isNotNull(AnnotationUtils.findAnnotation(bean.getClass(), FeignClient.class))) {
            // 排除含有 @Controller 和 @RestController 注解的bean
            if (StringUtils.isNotNull(AnnotationUtils.findAnnotation(bean.getClass(), Controller.class)) ||
                    StringUtils.isNotNull(AnnotationUtils.findAnnotation(bean.getClass(), RestController.class))) {
                return bean;
            }
            try {
                // 獲取代理類(lèi)中的 FeignInvocationHandler
                Field h = bean.getClass().getSuperclass().getDeclaredField("h");
                boolean hAccessible = h.isAccessible();
                h.setAccessible(true);
                Object feignInvocationHandler = h.get(bean);
                /**
                 * 獲取 FeignInvocationHandler 中 dispatch 字段的 Map<Method, MethodHandler> dispatch 屬性。
                 * dispatch中包含feign代理的方法 和 SynchronousMethodHandler
                 */
                Field dispatchField = feignInvocationHandler.getClass().getDeclaredField("dispatch");
                boolean dispatchAccessible = dispatchField.isAccessible();
                dispatchField.setAccessible(true);
                Map<Method, InvocationHandlerFactory.MethodHandler> dispatch =
                        (Map<Method, InvocationHandlerFactory.MethodHandler>) dispatchField.get(feignInvocationHandler);
                /**
                 * SynchronousMethodHandler 中的 List<RequestInterceptor> requestInterceptors 字段
                 * 加載了Hmily對(duì)feign的攔截器 HmilyFeignInterceptor
                 */
                for (Map.Entry<Method, InvocationHandlerFactory.MethodHandler> entry : dispatch.entrySet()) {
                    /**
                     * 沒(méi)有添加 @Hmily 注解的方法不需要被 Hmily 攔截處理,
                     * 否則會(huì)因?yàn)榧虞d的 HmilyTransactionContext 為 null 導(dǎo)致 NullPointerException
                     */
                    if (StringUtils.isNull(AnnotationUtils.findAnnotation(entry.getKey(), Hmily.class))) {
                        Field riField = entry.getValue().getClass().getDeclaredField("requestInterceptors");
                        boolean riAccessible = riField.isAccessible();
                        riField.setAccessible(true);
                        List<RequestInterceptor> requestInterceptors = (List<RequestInterceptor>) riField.get(entry.getValue());
                        for (RequestInterceptor interceptor : requestInterceptors) {
                            if (interceptor instanceof HmilyFeignInterceptor) {
                                requestInterceptors.remove(interceptor);
                                break;
                            }
                        }
                        riField.setAccessible(riAccessible);
                        log.info("{}.{} 方法移除 HmilyFeignInterceptor", beanName, entry.getKey().getName());
                    }
                }
                dispatchField.setAccessible(dispatchAccessible);
                h.setAccessible(hAccessible);
            } catch (Exception e) {
                log.warn("{} exception", beanName);
                e.printStackTrace();
            }
        }
        return bean;
    }
}

java.lang.NullPointerException出現(xiàn)的幾種原因及解決

出現(xiàn)的原因

1、字符串變量未初始化

2、接口類(lèi)型的對(duì)象沒(méi)有用具體的類(lèi)初始化,比如:

Map map // 會(huì)報(bào)錯(cuò)
Map map = new Map(); //則不會(huì)報(bào)錯(cuò)了

3、當(dāng)一個(gè)對(duì)象的值為空時(shí),你沒(méi)有判斷為空的情況。

4、字符串與文字的比較,文字可以是一個(gè)字符串或Enum的元素,如下會(huì)出現(xiàn)異常

String str = null;
if(str.equals(“Test”)){undefined
//這里的代碼將不會(huì)被觸發(fā),因?yàn)闀?huì)拋出java.lang.NullPointerException異常。
}

5、優(yōu)先使用String.valueOf()方法代替toString()

當(dāng)程序代碼需要對(duì)象的字符串表示形式時(shí),請(qǐng)避免使用該對(duì)象的toString方法。如果你的對(duì)象的引用等于null,NullPointerException則會(huì)拋出,使用靜態(tài)String.valueOf方法,該方法不會(huì)拋出任何異常并打印"null"

6、class被聲明了類(lèi)型, 默認(rèn) class = null; 這樣在調(diào)用class中方法的時(shí)候系統(tǒng)只能給你個(gè)空指針異常, 給其實(shí)例化就好了:class = new Class();

7、返回null,方法的返回值不要定義成為一般的類(lèi)型,而是用數(shù)組。這樣如果想要返回null的時(shí)候就能避免許多不必要的NullPointerException

我加粗的兩個(gè)是比較常見(jiàn)的,容易忽略的錯(cuò)誤,

大部分都是字符串比較的時(shí)候由于str=null,那么使用str.equals(“Test”)就會(huì)拋出異常

null不能和字符串進(jìn)行比較

解決的辦法有兩種:

  • 就是在比較之前判斷字符串是否為空
  • 當(dāng)傳入的參數(shù)str是空值的時(shí)候,程序就會(huì)異常,正確的是應(yīng)該把字符串放在前面
"Test".equals(str)

推薦使用第二種。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java簡(jiǎn)單實(shí)現(xiàn)農(nóng)夫過(guò)河問(wèn)題示例

    Java簡(jiǎn)單實(shí)現(xiàn)農(nóng)夫過(guò)河問(wèn)題示例

    這篇文章主要介紹了Java簡(jiǎn)單實(shí)現(xiàn)農(nóng)夫過(guò)河問(wèn)題,簡(jiǎn)單描述了農(nóng)夫過(guò)河問(wèn)題的概念、原理并結(jié)合簡(jiǎn)單實(shí)例形式分析了java解決農(nóng)夫過(guò)河問(wèn)題的相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • SpringBoot使用Guava實(shí)現(xiàn)日志脫敏的示例代碼

    SpringBoot使用Guava實(shí)現(xiàn)日志脫敏的示例代碼

    本文主要介紹了SpringBoot使用Guava實(shí)現(xiàn)日志脫敏的示例代碼,使用Guava中的Strings、Maps和CharMatcher類(lèi)來(lái)進(jìn)行日志脫敏,保護(hù)敏感數(shù)據(jù)的安全,感興趣的可以了解一下
    2024-01-01
  • idea開(kāi)啟mybatis控制臺(tái)SQL日志打印的代碼示例

    idea開(kāi)啟mybatis控制臺(tái)SQL日志打印的代碼示例

    本文主要介紹了idea開(kāi)啟mybatis控制臺(tái)SQL日志打印的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-12-12
  • Java?hutool?List集合對(duì)象拷貝示例代碼

    Java?hutool?List集合對(duì)象拷貝示例代碼

    這篇文章主要介紹了Java?hutool?List集合對(duì)象拷貝的相關(guān)資料,文章還分享了在實(shí)現(xiàn)過(guò)程中遇到的一些問(wèn)題,并強(qiáng)調(diào)了閱讀源碼和正確配置CopyOptions的重要性,需要的朋友可以參考下
    2024-12-12
  • Java下載Excel模板文件的簡(jiǎn)單實(shí)現(xiàn)方法

    Java下載Excel模板文件的簡(jiǎn)單實(shí)現(xiàn)方法

    這篇文章主要給大家介紹了關(guān)于Java下載Excel模板文件的簡(jiǎn)單實(shí)現(xiàn)方法,日常工作中可能經(jīng)常會(huì)涉及到用java開(kāi)發(fā)報(bào)表,需求比較多的就是表格類(lèi)的報(bào)表導(dǎo)出,單元格合并,圖表的展現(xiàn),需要的朋友可以參考下
    2023-07-07
  • MybatisPlus 自定義.vm模板的生成

    MybatisPlus 自定義.vm模板的生成

    為更加快捷方便的開(kāi)發(fā)代碼,使用MybatisPlus的代碼自動(dòng)生成功能,將一些繁瑣的操作自動(dòng)生成,本文主要介紹了MybatisPlus 自定義.vm模板的生成,感興趣的可以了解一下
    2024-03-03
  • java、js中實(shí)現(xiàn)無(wú)限層級(jí)的樹(shù)形結(jié)構(gòu)方法(類(lèi)似遞歸)

    java、js中實(shí)現(xiàn)無(wú)限層級(jí)的樹(shù)形結(jié)構(gòu)方法(類(lèi)似遞歸)

    下面小編就為大家?guī)?lái)一篇java、js中實(shí)現(xiàn)無(wú)限層級(jí)的樹(shù)形結(jié)構(gòu)方法(類(lèi)似遞歸)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • Java關(guān)鍵字synchronized基本使用詳解

    Java關(guān)鍵字synchronized基本使用詳解

    這篇文章主要給大家介紹了關(guān)于Java關(guān)鍵字synchronized基本使用的相關(guān)資料,synchronized可以用來(lái)同步靜態(tài)和非靜態(tài)方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Spring基礎(chǔ)之AOP的概念介紹

    Spring基礎(chǔ)之AOP的概念介紹

    AOP是Spring的關(guān)鍵特性之一,雖然Spring的IOC特性并不依賴于AOP,本文重點(diǎn)介紹AOP編程中的一些術(shù)語(yǔ),這些術(shù)語(yǔ)不僅僅局限于Spring,它適用于所有的AOP編程,感興趣的朋友一起看看吧
    2022-06-06
  • Java責(zé)任鏈設(shè)計(jì)模式實(shí)例分析

    Java責(zé)任鏈設(shè)計(jì)模式實(shí)例分析

    這篇文章主要介紹了Java責(zé)任鏈設(shè)計(jì)模式,結(jié)合實(shí)例形式詳細(xì)分析了Java責(zé)任鏈設(shè)計(jì)模式的原理與相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07

最新評(píng)論

平原县| 衡东县| 和田市| 延川县| 广安市| 江永县| 曲松县| 泰来县| 定南县| 北辰区| 芜湖市| 上饶市| 岳阳市| 贺州市| 景东| 铁岭市| 嘉兴市| 沾化县| 义马市| 郧西县| 石首市| 福建省| 英德市| 邵阳市| 义马市| 桦甸市| 梅河口市| 信丰县| 报价| 凯里市| 济南市| 吴桥县| 玛沁县| 鹿邑县| 耿马| 商水县| 特克斯县| 鹤庆县| 栖霞市| 西和县| 牡丹江市|