springcloud-alibaba feign整合sentinel 报不满足依赖错误

在feign整合sentinel时遇到了一个问题,折腾了一天,发现是@EnableFeignClients扫包的问题

具体错误:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController': Unsatisfied dependency expressed through field 'productService'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.yushanma.service.ProductService': FactoryBean threw exception on object creation; nested exception is java.lang.NullPointerException
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1415) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:608) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:531) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:923) ~[spring-context-5.3.3.jar:5.3.3]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:588) ~[spring-context-5.3.3.jar:5.3.3]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) ~[spring-boot-2.4.2.jar:2.4.2]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~[spring-boot-2.4.2.jar:2.4.2]
	at com.yushanma.TestApplication.main(TestApplication.java:21) ~[classes/:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.yushanma.service.ProductService': FactoryBean threw exception on object creation; nested exception is java.lang.NullPointerException
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:176) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:101) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1884) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getObjectForBeanInstance(AbstractAutowireCapableBeanFactory.java:1268) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:267) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1605) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1562) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1343) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.3.jar:5.3.3]
	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.3.3.jar:5.3.3]
	... 20 common frames omitted
Caused by: java.lang.NullPointerException: null
	at com.alibaba.cloud.sentinel.feign.SentinelFeign$Builder$1.create(SentinelFeign.java:92) ~[spring-cloud-starter-alibaba-sentinel-2020.0.RC1.jar:2020.0.RC1]
	at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:64) ~[feign-core-10.10.1.jar:na]
	at feign.Feign$Builder.target(Feign.java:269) ~[feign-core-10.10.1.jar:na]
	at org.springframework.cloud.openfeign.DefaultTargeter.target(DefaultTargeter.java:30) ~[spring-cloud-openfeign-core-3.0.0.jar:3.0.0]
	at org.springframework.cloud.openfeign.FeignClientFactoryBean.loadBalance(FeignClientFactoryBean.java:306) ~[spring-cloud-openfeign-core-3.0.0.jar:3.0.0]
	at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:335) ~[spring-cloud-openfeign-core-3.0.0.jar:3.0.0]
	at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:315) ~[spring-cloud-openfeign-core-3.0.0.jar:3.0.0]
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:169) ~[spring-beans-5.3.3.jar:5.3.3]
	... 31 common frames omitted


Process finished with exit code 1

虽然用了@EnableFeignClients注解,但是在微服务多模块项目中也扫不到@FeignClient注解的类,这个类没有生成实例,在controller中@Autowire就没有办法注入依赖,最后报不满足依赖的错误。

解决方法:指定扫描@FeignClient所在的包路径

package com.yushanma;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication//(scanBasePackages = {"com.yushanma.service","com.yushanma.controller"})
//@EnableDiscoveryClient
@EnableFeignClients(basePackages="com.yushanma.fallback")
//@EnableFeignClients
//@SpringCloudApplication
@MapperScan("com.pojo.mapper")
public class TestApplication {
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class);
    }
}

关闭商品微服务后,订单微服务进入容错逻辑

完整代码

package com.yushanma.service;

//Product product =
//        restTemplate.getForObject("http://" + url + "/product/" + pid, Product.class);


import com.pojo.model.Product;
import com.yushanma.config.FeignConfiguration;
import com.yushanma.fallback.EchoServiceFallback;
import com.yushanma.fallback.EchoServiceFallbackFactory;
import com.yushanma.fallback.ProductServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Primary;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(
        name = "service-product",
//        fallback = ProductServiceFallback.class
//        fallbackFactory = ProductServiceFallBackFactory.class
        fallbackFactory = EchoServiceFallbackFactory.class,
        primary = true
//        fallback = EchoServiceFallback.class,
//        configuration = FeignConfiguration.class
)

public interface ProductService {

    //@FeignClient+@GetMapping 就是一个完整的请求路径 http://service-product/product/{pid}
    @RequestMapping(method = RequestMethod.GET, value = "/product/{pid}")
    Product findByPid(@PathVariable("pid") Integer pid);
}

package com.yushanma.fallback;

import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

@Component
public class EchoServiceFallbackFactory implements FallbackFactory<EchoServiceFallback> {

    @Override
    public EchoServiceFallback create(Throwable throwable) {
        return new EchoServiceFallback(throwable);
    }

}
package com.yushanma.fallback;

import com.pojo.model.Product;
import com.yushanma.service.ProductService;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class EchoServiceFallback implements ProductService {
    private Throwable throwable;

    EchoServiceFallback(Throwable throwable) {
        this.throwable = throwable;
    }

    @Override
    public Product findByPid(Integer pid) {
        Product product = new Product();
        product.setPid(-1);
        product.setPname("product-service调用出错,进入容错逻辑");
//        log.info("{}",throwable.getMessage());
        return product;
    }
}
package com.yushanma.controller;

import com.alibaba.fastjson.JSON;
import com.pojo.model.Order;
import com.pojo.model.Product;
import com.yushanma.service.OrderService;
import com.yushanma.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class ProductController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private ProductService productService;

    //  基于Ribbon实现负载均衡
    @RequestMapping("order/prod/{pid}")
    public Order order(@PathVariable("pid") Integer pid) {
        log.info("查询商品{}", pid);
        Product product = productService.findByPid(pid);
        //容错处理
        if (product.getPid() == -1) {
            Order order = new Order();
            order.setPname("下单失败");
            return order;

        }
        log.info("查询到的商品信息为{}", JSON.toJSONString(product));
        Order order = new Order();
        order.setUid(1);
        order.setUsername("yushanma");
        order.setPid(pid);
        order.setPname(product.getPname());
        order.setPprice(product.getPprice());
        order.setNumber(1);
//        orderService.createOrder(order);
        log.info("创建新的订单{}", JSON.toJSONString(order));
        return order;
    }
}

但是出现后续问题:无论商品微服务是否开启,订单微服务一直进入容错逻辑

发现是(basePackages="com.yushanma.fallback")的问题,应指定为"com.yushanma.service",但还是报空指针错误。最终考虑更换父工程版本:

    <!--    父工程-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
    </parent>
    <!--版本依赖的锁定-->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
    </properties>

去掉feign的版本指定:

        <!--fegin组件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- Feign Client for loadBalancing -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>

不需再指定扫包:

开启两个服务后:请求下单成功

关闭商品微服务后下单:进入容错逻辑

至此,feign整合sentinel完成。

参考:

https://www.cnblogs.com/keeya/p/14476548.html

https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/#spring-cloud-feign-overriding-defaults

https://segmentfault.com/a/1190000018914017

https://github.com/alibaba/spring-cloud-alibaba/tree/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余衫马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值