@Autoware 自动注入成员变量位置调用方法空指针
- 问题描述: 在使用 springcloud 中 eureka 注册中心注册写消费者和提供者时,在消费者代码成员变脸中报出空指针异常 .
@RestController
@RequestMapping("/consumer")
@Slf4j
public class UserController {
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private RestTemplate restTemplate;
//报错代码位置
//报错代码原因:空指针
List<ServiceInstance> instances = discoveryClient.getInstances("provider-service");
ServiceInstance instance = instances.get(0);
uri = instance.getUri();
/**
* 测试get请求提交方式
* @return
*/
@GetMapping
public String getType(){
//用DiscoveryClient类的方法,根据服务名称,获取服务实例
log.info("============欢迎访问==========");
String result = restTemplate.getForObject(uri+"/hello", String.class);
return result;
}
}
原因总结 :
由于启动配置类的时,会将所有的对象实例化到IOC容器中,在实例化的过程中,会加载到成员变量,此时还未完成自动注入(所有对象完成实例化后在自动注入),所以在调用方法会报空指针错误 .
-
解决思路
- 使用
@PostConstruct
注解 , 让对象完成自动注入后在调用方法
@RestController @RequestMapping("/consumer") @Slf4j public class UserController { @Autowired private DiscoveryClient discoveryClient; @Autowired private RestTemplate restTemplate; private URI uri; @PostConstruct public void init(){ List<ServiceInstance> instances = discoveryClient.getInstances("provider-service"); ServiceInstance instance = instances.get(0); uri = instance.getUri(); } /** * 测试get请求提交方式 * @return */ @GetMapping public String getType(){ //用DiscoveryClient类的方法,根据服务名称,获取服务实例 log.info("============欢迎访问=========="); String result = restTemplate.getForObject(uri+"/hello", String.class); return result; } }
- 抽取成方法直接使用
public URI getURI(){ List<ServiceInstance> instances = discoveryClient.getInstances("provider-service"); ServiceInstance instance = instances.get(0); URI uri = instance.getUri(); return uri; } /** * 测试get请求提交方式 * @return */ @GetMapping public String getType(){ //用DiscoveryClient类的方法,根据服务名称,获取服务实例 log.info("============欢迎访问=========="); String result = restTemplate.getForObject(getURI()+"/hello", String.class); return result; } }
- 使用