报错信息如下:
Field discoveryClient in ........................ required a bean of type 'com.netflix.discovery.DiscoveryClient' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
这个原因是启动器引入的eureka的发现注解和在进行注入地时候所使用的包不是同一个:比如我这种情况:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import tk.mybatis.spring.annotation.MapperScan;
@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("cn.itcast.user.mapper")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class,args);
}
}
启动器这边我引入的是:import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 这个包,而在controller中:
import cn.itcast.comsumer.pojo.User;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
// http://localhost:8082/consumer/2
@GetMapping("{id}")
public User queryById(@PathVariable("id") Long id){
// 根据服务id获取实例
List<InstanceInfo> instances = discoveryClient.getInstancesById("user-service");
// 从实例中取出ip和端口
InstanceInfo instance = instances.get(0);
String url = "http://"+instance.getHostName()+":"+instance.getPort()+"/user/"+id;
User user = restTemplate.getForObject(url,User.class);
return user;
}
}
我这边引入的包是:import com.netflix.discovery.DiscoveryClient;
这就是我在启动器所引入的bean和我在controller中所取bean不是同一个。
意思是:我想IOC容器索要一个 com.netflix.discovery.DiscoveryClient类的 bean,而我只在容器中 注册了 org.springframework.cloud.client.discovery.EnableDiscoveryClient类的 bean,这就是不一致,从而就报错。
解决办法:
只要将取得bean和拿的bean是同一个就行了。
我这边是将controller中所注入得bean改为启动器中放入得bean。
controller修改如下:
import cn.itcast.comsumer.pojo.User;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient; # 修改1
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
// http://localhost:8082/consumer/2
@GetMapping("{id}")
public User queryById(@PathVariable("id") Long id){
// 根据服务id获取实例
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");# 修改2
// 从实例中取出ip和端口
ServiceInstance instance = instances.get(0);# 修改3
String url = "http://"+instance.getHost()+":"+instance.getPort()+"/user/"+id;#修改4
User user = restTemplate.getForObject(url,User.class);
return user;
}
}