多平台统一管理软件接口,如何实现多平台统一管理软件接口
324
2022-09-14
解决Hmily与Feign冲突报错 NullPointerException的问题
目录Hmily与Feign冲突报错 NullPointerException解决方法java.lang.NullPointerException出现的几种原因及解决出现的原因
Hmily与Feign冲突报错 NullPointerException
在项目中使用了Hmily保证分布式事务的一致性,由于Hmily会注册一个 HmilyFeignInterceptor ,并且feign会将其添加到 SynchronousMethodHandler 中的 requestInterceptors ,当feign客户端执行 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
* dispatch中包含feign代理的方法 和 SynchronousMethodHandler
*/
Field dispatchField = feignInvocationHandler.getClass().getDeclaredField("dispatch");
boolean dispatchAccessible = dispatchField.isAccessible();
dispatchField.setAccessible(true);
Map
(Map
/**
* Synchronohttp://usMethodHandler 中的 List
* 加载了Hmily对feign的拦截器 HmilyFeignInterceptor
*/
for (Map.Entry
/**
* 没有添加 @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
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出现的几种原因及解决
出现的原因
1、字符串变量未初始化
2、接口类型的对象没有用具体的类初始化,比如:
Map map // 会报错
Map map = new Map(); //则不会报错了
3、当一个对象的值为空时,你没有判断为空的情况。
4、字符串与文字的比较,文字可以是一个字符串或Enum的元素,如下会出现异常
String str = null;
if(str.equals(“Test”)){undefined
//这里的代码将不会被触发,因为会抛出java.lang.NullPointerException异常。
}
5、优先使用String.valueOf()方法代替toString()
当程序代码需要对象的字符串表示形式时,请避免使用该对象的toString方法。如果你的对象的引用等于null,NullPointerException则会抛出,使用静态String.valueOf方法,该方法不会抛出任何异常并打印"null"
6、class被声明了类型, 默认 class = null; 这样在调用class中方法的时候系统只能给你个空指针异常, 给其实例化就好了:class = new Class();
7、返回null,方法的返回值不要定义成为一般的类型,而是用数组。这样如果想要返回null的时候就能避免许多不必要的NullPointerException
我加粗的两个是比较常见的,容易忽略的错误,
大部分都是字符串比较的时候由于str=null,那么使用str.equals(“Test”)就会抛出异常
null不能和字符串进行比较
解决的办法有两种:
就是在比较之前判断字符串是否为空
当传入的参数str是空值的时候,程序就会异常,正确的是应该把字符串放在前面
"Test".equals(str)
推荐使用第二种。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~