解决Hmily与Feign冲突报错NullPointerException的问题的完整攻略如下:
- 引入Hmily和Feign的依赖
在使用Hmily和Feign时需要引入它们的依赖,比如在Maven中可以使用以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>hmily-spring-cloud-starter</artifactId>
<version>${hmily.version}</version>
</dependency>
其中${hmily.version}
为需要使用的Hmily版本号。
- 报错信息
当使用Hmily和Feign时可能会出现冲突,导致出现NullPointerException报错信息,如下所示:
java.lang.NullPointerException: null
at org.dromara.hmily.core.utils.HolderUtils.clear() ~[hmily-core-2.0.6.jar:2.0.6]
at org.dromara.hmily.spring.interceptor.HmilyFeignInterceptor.remove() ~[hmily-spring-2.0.6.jar:2.0.6]
at org.dromara.hmily.spring.interceptor.HmilyFeignInterceptor.intercept(HmilyFeignInterceptor.java:47) ~[hmily-spring-2.0.6.jar:2.0.6]
通过报错信息可以知道,出现了一个NullPointerException,而出现异常的地方是在org.dromara.hmily
和org.springframework.cloud.openfeign
这两个包中。
- 解决方案
解决这个问题的方法比较简单,只需要将Hmily的Feign拦截器换成自定义的拦截器即可。具体步骤如下:
首先,在使用Hmily时需要在配置文件中配置相关参数,比如以下配置:
spring:
application:
name: demo
cloud:
nacos:
discovery:
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
sentinel:
transport:
dashboard: localhost:8080
feign:
hystrix:
enabled: true
client:
config:
default:
connectTimeout: 5000
readTimeout: 10000
# 此处将Hmily的拦截器类名配置为自定义的拦截器
requestInterceptors: com.example.feign.MyFeignInterceptor
可以看到,此处将requestInterceptors
配置项的值修改为自定义的MyFeignInterceptor
拦截器类名。
然后,在自定义的MyFeignInterceptor
中实现RequestInterceptor
接口,并重写apply
方法,示例代码如下:
import feign.RequestInterceptor;
import feign.RequestTemplate;
public class MyFeignInterceptor implements RequestInterceptor {
// 在apply方法中可以对请求进行处理
@Override
public void apply(RequestTemplate requestTemplate) {
// 可以在这里添加自定义的处理逻辑
requestTemplate.header("Custom-Header", "Custom-Value");
}
}
可以看到,这个自定义拦截器类非常简单,只是在请求模板中添加了一个自定义的header,实际使用中可以根据自己的需求来编写处理逻辑。
最后,重新运行程序,就会发现Hmily和Feign可以正常工作了,不再出现NullPointerException的问题。
- 示例说明
以下是两个使用示例说明:
(1)使用Spring Cloud Alibaba官方提供的seata-spring-boot-starter
依赖中的SeataAutoConfiguration
类
在使用seata-spring-boot-starter
依赖中的SeataAutoConfiguration
类时,需要使用io.seata.spring.annotation.GlobalTransactionScanner
注解将这个类标注为bean,示例代码如下:
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SeataConfig {
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
return new GlobalTransactionScanner("my_tx_group", "my_app_name");
}
}
可以看到,这个全局事务扫描器需要指定一个事务分组和应用名称,然后将其返回作为bean。
如果此时引入了Hmily和Feign的依赖,并进行了相关的配置,那么就可能会出现上述的NullPointerException的问题。
解决这个问题只需要将使用io.seata.spring.annotation.GlobalTransactionScanner
的注解从@Bean
改成@Component
即可,示例代码如下:
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.springframework.stereotype.Component;
@Component
public class GlobalTransactionScannerComponent extends GlobalTransactionScanner {
public GlobalTransactionScannerComponent() {
super("my_tx_group", "my_app_name");
}
}
可以看到,在这个示例中,我们将GlobalTransactionScanner
扩展出一个自定义的组件,并在GlobalTransactionScanner
的构造函数中传入分组和应用名称。
然后,在这个自定义组件中将自己的类标注为@Component
,并将父类的构造函数调用放到构造函数中,从而将它作为bean交由Spring容器管理。
这样,就可以最大限度地兼容Seata和Hmily,并且不会出现NullPointerException的问题。
(2)在通过Feign调用Hmily接口时出现NullPointerException的问题
在通过Feign调用Hmily接口时,如果出现了NullPointerException的问题,可以按照上述步骤将Hmily的Feign拦截器换成自定义的拦截器,从而解决问题。具体的实现可以参考上述的解决方案中的示例代码。
可以看到,这个自定义的拦截器非常简单,只是在请求模板中添加了一个自定义的header,实际使用中可以根据自己的需求来编写处理逻辑。
然后,在application.yml
中将拦截器类名配置为自定义的拦截器即可,具体的实现可以参考上述的解决方案中的application.yml
配置代码。
这样,就可以使用Feign调用Hmily接口,并且不会出现NullPointerException的问题。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解决Hmily与Feign冲突报错 NullPointerException的问题 - Python技术站