欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解決Hmily與Feign沖突報錯 NullPointerException的問題

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

Hmily與Feign沖突報錯 NullPointerException

在項目中使用了Hmily保證分布式事務的一致性,由于Hmily會注冊一個 HmilyFeignInterceptor ,并且feign會將其添加到 SynchronousMethodHandler 中的 requestInterceptors ,當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 異常。

解決方法

定義一個后置處理器,將沒有被 @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 {
        // 對所有含有 @FeignClient 的bean進行處理
        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 {
                // 獲取代理類中的 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對feign的攔截器 HmilyFeignInterceptor
                 */
                for (Map.Entry<Method, InvocationHandlerFactory.MethodHandler> entry : dispatch.entrySet()) {
                    /**
                     * 沒有添加 @Hmily 注解的方法不需要被 Hmily 攔截處理,
                     * 否則會因為加載的 HmilyTransactionContext 為 null 導致 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、接口類型的對象沒有用具體的類初始化,比如:

Map map // 會報錯
Map map = new Map(); //則不會報錯了

3、當一個對象的值為空時,你沒有判斷為空的情況。

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

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

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

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

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

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

我加粗的兩個是比較常見的,容易忽略的錯誤,

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

null不能和字符串進行比較

解決的辦法有兩種:

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

推薦使用第二種。

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

相關文章

  • Java編程中靜態(tài)內(nèi)部類與同步類的寫法示例

    Java編程中靜態(tài)內(nèi)部類與同步類的寫法示例

    這篇文章主要介紹了Java編程中靜態(tài)內(nèi)部類與同步類的寫法示例,用于構(gòu)建靜態(tài)對象以及實現(xiàn)線程同步等,需要的朋友可以參考下
    2015-09-09
  • 理解 Java 核心基礎精髓解析

    理解 Java 核心基礎精髓解析

    這篇文章主要介紹了解 Java 核心基礎精髓解析問題,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-03-03
  • Java類的繼承原理與用法分析

    Java類的繼承原理與用法分析

    這篇文章主要介紹了Java類的繼承原理與用法,結(jié)合實例形式分析了java類的繼承相關原理、使用方法及操作注意事項,需要的朋友可以參考下
    2020-02-02
  • 查看Java所支持的語言及相應的版本信息

    查看Java所支持的語言及相應的版本信息

    Java語言作為第一種支持國際化的語言,在Internet從一開始就具有其他語言無與倫比的國際化的本質(zhì)特性,查看Java所支持的語言及相應的版本信息可以采用以下代碼進行查詢
    2014-01-01
  • Java日常練習題,每天進步一點點(27)

    Java日常練習題,每天進步一點點(27)

    下面小編就為大家?guī)硪黄狫ava基礎的幾道練習題(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-07-07
  • 一篇帶你解析入門LongAdder源碼

    一篇帶你解析入門LongAdder源碼

    LongAdder類是JDK1.8新增的一個原子性操作類。AtomicLong通過CAS算法提供了非阻塞的原子性操作,因為非常搞并發(fā)的請求下AtomicLong的性能是不能讓人接受的
    2021-06-06
  • Java8 Optional優(yōu)雅空值判斷的示例代碼

    Java8 Optional優(yōu)雅空值判斷的示例代碼

    這篇文章主要介紹了Java8 Optional優(yōu)雅空值判斷的相關知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • 關于spring data jpa一級緩存的問題

    關于spring data jpa一級緩存的問題

    這篇文章主要介紹了關于spring data jpa一級緩存的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 解決java junit單元測試@Test報錯的問題

    解決java junit單元測試@Test報錯的問題

    今天小編就為大家分享一篇解決java junit單元測試@Test報錯的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • spring中FactoryBean中的getObject()方法實例解析

    spring中FactoryBean中的getObject()方法實例解析

    這篇文章主要介紹了spring中FactoryBean中的getObject()方法實例解析,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02

最新評論