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完成参数的配置,实际上都是在解决我们最终的依赖与它们自己的依赖的组装问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/559045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑色玫瑰服务器延迟高,LOL:含金量最高的服务器,黑色玫瑰垫底,最后一个钻石起步!...

原标题:LOL:含金量最高的服务器,黑色玫瑰垫底,最后一个钻石起步!黑色玫瑰。它是英雄联盟中非常特别的一个大区。这个大区是中间位置,电十,却是比电二高手还要多的地方。因为这个大区小姐姐特别的…

redis学习与入门~~~

redis学习与入门~~~ 一。 Redis 简介: 通常而言目前的数据库分类有几种,包括 SQL/NSQL,,关系数据库,键值数据库等等,分类的标准也不1,Redis本质上也是一种键值数据库的,但它在保持键值数据库简单…

Java网络编程————UDP实现ThinkPad S5网络唤醒

功能要求:通过Java程序实现ThinkPad S5 笔记本网络唤醒 必备知识: 一、定义:网络唤醒,通过局域网、互联网或通讯网络,以有线网卡的形式,向目标电脑发送魔法包(Magic Packet),让电脑自动开机。…

FFmpeg在Ubuntu的安装以及教程~~~

FFmpeg在Ubuntu的安装以及教程~~~一、安装 可通过PPA进行安装sudo add-apt-repository ppa:kirillshkrogalev/ffmpeg-next sudo apt-get update sudo apt-get install ffmpeg 查看是否安装成功: ffmpeg -version二、相关概念比特率比特率,是一个决定音视…

Java学习指导————如何做到基础扎实

原文出处:《一篇文章教会你,如何做到招聘要求中的“要有扎实的Java基础”》 引言 不少同学总会产生这样的疑问: “请问,如何才叫基础扎实?” 答案是:“玩好JDK!” JDK学习内容主要包含三部分…

奥特曼系列ol服务器名称带怪兽,《奥特曼系列ol》怪兽图鉴 怪兽阵容

《奥特曼系列ol》这款游戏中的怪兽图鉴也是很多玩家非常关注的问题之一哦,随着游戏的不断的更新,游戏也是加入了不少全新的玩法,一定让很多玩家觉得有些迷惑吧。下面小编为大家带来《奥特曼系列ol》怪兽图鉴以及怪兽阵容,希望大家…

继上一篇博客--javaweb通过接口来实现多个文件压缩和下载(包括单文件下载,多文件批量下载)

通过动态分配地址来提升javaweb文件下载接口的其兼容性和可扩展性: (上篇博文地址:https://blog.csdn.net/weixin_37766296/article/details/80044000)log4j.properties 文件: log4j.rootLogger debug,stdout,D,Elog4…

服务器主机启动不显示,服务器主机不启动怎么回事

服务器主机不启动怎么回事 内容精选换一换本文介绍了主机迁移服务SMS各特性版本的功能发布和对应的文档动态,新特性将在各个区域(Region)陆续发布,欢迎体验。源端服务器数据收集声明。源端服务器上安装和配置完迁移Agent后,迁移Agent会把源端…

Swagger自动接口文档生成框架————springboot整合swagger总结

swagger简介: swagger是一款开源的api接口文档生成工具。 Swagger的项目主页:https://swagger.io/ 目前比较流行的做法是在代码中加入swagger相关的注释,然后,利用小工具生成swagger.json或者swagger.yaml文件。 springboot…

申请 Let's Encrypt 数字证书,并安装cerbot快速上手教程~~

申请 Lets Encrypt 数字证书,并安装cerbot快速上手教程~~Let‘s Encrypt SSL证书介绍如今,越来越多的网站已经由HTTP迁移到HTTPS安全协议了。HTTPS不但能够避免网站内容在传输过程中被恶意篡改,切实保护访问者的权益,还能够让搜索…

Java常用设计模式————单例模式

单例模式简介 90%以上的设计模式都或多或少的应用了接口和抽象类,而单例比较特殊,并没有接口的应用。 单例Singleton指仅仅被实例化一次的类。通常被用来代表那些本质上唯一的系统组件。————《Effective Java》 数据库连接获取类的对象可以是单例的…

最简明扼要的 Systemd 教程,只需十分钟

systemctl常用命令介绍~~~Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器。 Systemd是一个系统管理守护进程、工具和库的集合,用于取代System V初始进程。Systemd的功能是用于集中管理和配置类UNIX系统。启动及服务大多数主流发行版要…

Java常用设计模式————工厂模式

简介: 工厂模式(Factory Pattern)是Java中最常用的设计模式之一,又称多态工厂模式、虚拟构造器模式。属于创建型模式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的…

JavaScript新手入门教程大全~~~

JavaScript新手入门教程大全~~~一。 js教程介绍:JavaScript是一种运行在浏览器中的解释型的编程语言。 那么问题来了,为什么我们要学JavaScript?因为你没有选择。在Web世界里,只有JavaScript能跨平台、跨浏览器驱动网页&#xff0…

Java常用设计模式————抽象工厂模式

简介 每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。 与工厂方法模式的区别 工厂方法模式针对的是一个产品等级结构,而抽象工厂模式针对的是多个产品等级结构,因此抽象工厂模式在结构上要比工厂方法模式更加复杂和抽象,也更…

CSS新手入门教程~~~~

CSS新手入门教程~~~~CSS简介:什么是 CSS? CSS 指层叠样式表 (Cascading Style Sheets)样式定义如何显示 HTML 元素样式通常存储在样式表中把样式添加到 HTML 4.0 中,是为了解决内容与表现分离的问题外部样式表可以极大提高工作效率外部样式表通常存储在…

Docker必备知识整理

Docker简介 Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 Docker是用Go语言…

Exception和Error深入分析~~~

Exception和Error深入分析~~~Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。 Exception 和 Erro…

Java常用设计模式————原型模式(一)

介绍 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。 原型模式用于创建重复的对象,同时又能保证性能。当直接创建对象的代价比较大时,则采用这种模式。&…

解决eclipse刚启动卡死的问题~~~亲测有效~~

解决eclipse刚启动卡死的问题~~~亲测有效~~ 重启了eclipse三次,还是卡死了。最后找到一下方法: 建议大家在删除先备份一下文件,以免丢失项目! 关于 eclipse启动卡死的问题(eclipse上一次没有正确关闭,导致…