SpringBoot学习——@Autowired自动注入报:could not be found问题的理解和解决方案
微服务应用程序中,我们会通过Java后台的方式发送http请求并调用其他注册在Spring Cloud Eureka server上的微服务,之前我们可能会手动封装一个Http发送请求类,然后通过其中的sendGet或者sendPost方法借由java IO的形式发送出去。
但是,上述方法过于繁琐和和臃肿,我们使用org.springframework.web.client.RestTemplate实例,通过几行代码就可以轻松发送我们需要的请求。
然而,在实际的应用程序调用时,我通过@Autowired方式将RestTemplate实例注入到类中,
@Autowiredprivate RestTemplate restTemplate;
在启动springboot时,控制台报告启动失败:
***************************
APPLICATION FAILED TO START
***************************Description:Field restTemplate in com.seco.ad.controller.MobileAdController required a bean of
type 'org.springframework.web.client.RestTemplate' that could not be found.Action:Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
可以看到Description:中的描述是RestTemplate未能找到!!!
为什么?因为Spring容器没有注册RestTemplate实例,也就无法通过@Autowired自动注入方式“new”一个RestTemplate实例出来(通过重写无参构造器的方式,可以发现这种通过@Autowired方式自动注入的实例确实是通过new方法来完成的)。
在之前的@Autowired注解使用中,我们可以轻松的将DAO层的依赖对象JdbcTemplate实例顺利的自动注入到DAO层的服务中去,而不需要任何类似JavaConfig或者xml配置Bean定义到Spring容器中去,那为什么RestTemplate就需要?
原来JdbcTemplate 和RestTemplate一样都是都是spring框架本身提供的组件,但是项目中用到的JdbcTemplate是不需要参数的,可以通过@Autowired自动注入,而不需要初始化,但是RestTemplate需要。另外,在《@Autowired自动注入实例》这篇文章中也可以看到,当需要参数的JdbcTemplate进行自动注入的时候应用程序在启动时就会发生类似“could not be found”的空指针异常。
因此,回过头来反思@Autowired自动注入RestTemplate报“could not be found”错误的原因,即是此注入实例需要参数!
我在通过网上资料的查询中找到了正确注入RestTemplate的方法,确实需要将RestTemplate注册到spring容器中去,另外,还有我们刚刚提到的参数问题,也就是RestTemplate实例的依赖:org.springframework.http.client.ClientHttpRequestFactory。
SpringBoot提倡通过JavaConfig方式注册我们需要的Bean元素:
package com.seco.ad.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;/*** RestTemplate配置* 这是一种JavaConfig的容器配置,用于spring容器的bean收集与注册,并通过参数传递的方式实现依赖注入。* "@Configuration"注解标注的配置类,都是spring容器配置类,springboot通过"@EnableAutoConfiguration"* 注解将所有标注了"@Configuration"注解的配置类,"一股脑儿"全部注入spring容器中。* * @author mht**/
@Configuration
public class RestTemplateConfig {@Beanpublic RestTemplate restTemplate(ClientHttpRequestFactory factory) {return new RestTemplate(factory);}@Beanpublic ClientHttpRequestFactory simpleClientHttpRequestFactory() {SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();factory.setReadTimeout(5000);//msfactory.setConnectTimeout(15000);//msreturn factory;}
}
(最近在研读《SpringBoot揭秘》有关springboot启动方面的知识中谈到了有关@Configuration注解的的作用我写在了这段code中的JavaDoc里)
可以看到,在此JavaConfig配置中,我注册了两个Bean,而第二个Bean正是我们最终需要的RestTemplate实例的依赖,有了这个配置类,我们回过头再通过@Autowired方式自动注入我们需要的RestTemplate就不会在springboot启动时报“无法找到”错误了。
令人欣喜的是,将这些思路理清的功臣是《@Autowired自动注入实例》这篇文章。
我试着通过文章中提到的“@Autowired自动注入有参数依赖对象的写法”编写类似的代码后,发现即便是没有RestTemplateConfig这个配置类,没有对spring容器进行bean定义的注册,依然可以成功的启动springboot应用程序。写法如下:
private RestTemplate restTemplate;private ClientHttpRequestFactory factory;@Autowiredpublic void setFactory() {SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();factory.setReadTimeout(5000);//msfactory.setConnectTimeout(15000);//msthis.factory = factory;}@Autowiredpublic void setRestTemplate() {this.restTemplate = new RestTemplate(this.factory);}
上述代码思路很简单:设置两个私有属性 restTemplate和factory,然后下面先通过设置参数的方式自动完成对factory对象的注入,然后再讲factory注入到restTemplate中去,即完成了RestTemplate的注入工作。即便没有JavaConfig这样的Bean的注册配置类,应用程序依然可以启动成功。
实际上还是围绕了spring容器的关键两步(引自王富强的《SpringBoot解密》):第一步:收集和注册;第二步:分析和组装。
当我们依赖的实例(例如本文中提到的JdbcTemplate和RestTemplate)需要其他的依赖时,当然就不可能仅仅通过@Autowired自动注入到我们需要的类中而不去考虑它们的参数(也就是它们的依赖),因此,不管是通过JavaConfig配置方式还是利用@Autowired完成参数的配置,实际上都是在解决我们最终的依赖与它们自己的依赖的组装问题。
SpringBoot学习——@Autowired自动注入报:could not be found问题的理解和解决方案相关推荐
- 【ActiveMQ】消息生产者自动注入报错:Could not autowire. No beans of 'JmsMessagingTemplate' type found
标签:public style hat and 报错 require core ota ati 使用ActiveMQ过程中,定义消息生产者: package com.s ...
- 解决非controller使用@Autowired注解注入报错为java.lang.NullPointerException问题
解决非controller使用@Autowired注解注入报错为java.lang.NullPointerException问题 参考文章: (1)解决非controller使用@Autowired注 ...
- spring源码解析(二) @Autowired自动注入过程
1.依赖注入到底有几种?两种.四种.五种? 两种: 手动:set(byType.byName).构造器 自动:xml中:set.构造器 autowired注解中:set.属性.构造器 重点不在于到底有 ...
- springboot单元测试中@Autowired自动注入的类一直是null
另附大佬方法
- 【ActiveMQ】消息生产者自动注入报错:Could not autowire. No beans of 'JmsMessagingTemplate' type found...
使用ActiveMQ过程中,定义消息生产者: package com.sxd.jms.producer;import org.springframework.beans.factory.annotat ...
- @Autowired自动注入
1.默认优先按照类型去容器中找对应的组件 applicationContext.getBean(XXX.class) 2.如果找到了多个相同类型相同的组件 ,再将属性的名称作为组件的id去容器中查找 ...
- SpringBoot 中@Autowired 注入失效原因及解决方法
SpringBoot 中@Autowired 注入失效原因及解决方法 1.原因分析 1.1 包没有被扫描到通过@Autowired注入的类所在的包路径不在Application启动类所在的包/子包路径 ...
- @Autowired自动装配
@Autowired自动装配!!! 在不使用xml配置文件时,@Autowired是我们使用最多的注解之一,关于该注解的原理如下: @Autowired原理:在启动springIoC时,容器自动装载了 ...
- springboot找不到对象(自动注入失败)
springboot找不到对象(自动注入失败) 今天在idea重新建立个springboot项目时,遇到这个奇怪的问题,说是找不到对应的bean,我猜想是@Mapper的问题 Error starti ...
最新文章
- ecshop将编辑器更换为kindeditor
- ios 应用 开发流程。。。
- Entity Framework 5.0基础系列
- 基于深度学习的医学图像分割综述
- 使用Actuator检查与监控
- AngelToken揭秘区块链之四大链
- 从时速100公里行驶的车上向后发射时速100公里的棒球,会发生什么?
- 《Python学习之路 -- 字符串的方法》
- 玩转oracle 11g(24):数据文件设置自扩展和监听日志文件过大处理
- 如何区分普通感冒流感和新型冠状病毒肺炎?
- hive如何获取当前时间
- 计算机单词 硬件类、软件类、网络类、其他
- C语言实现顺序表基本操作
- Md5,base64加密
- Permute 3 for mac(万能音视频转换器)
- 六十秒倒计时android,如何用jquery实现六十秒倒计时
- P 哥的桶(线段树+线性基)
- 51单片机入门——数模\模数转换
- 数据集:大学毕业生收入
- H264(AVC)/H265(HEVC)/H266(VVC):GOP的区别
热门文章
- java 生产者消费者代码_Java生产者和消费者代码
- Java文件类boolean canWrite()方法(带示例)
- c printf 段错误_错误:预期声明在C中的printf之前指定
- 第 5-2 课:线程池——ThreadPoolExecutor + 面试题
- 第一弹!安利10个让你爽到爆的IDEA必备插件!
- WordPress网站搬家教程(根目录程序+ MySQL数据库)
- 微信开发之——Ubuntu Apache2的https域名配置
- 华为数据通信产品VRP操作系统的使用
- 求1+2+3+……+100的累加和。
- mysql jdbc 绑定变量_jdbc测试mysql数据库sql预解析(绑定变量)