Spring @Autowired 用法

news/2023/6/9 20:00:45

Spring @Autowired 用法

  • 首先看下@Component
    • ```举例 1 :```
    • ```举例 2 :```
    • 验证是否调用的是默认构造器
    • ```如何,在启动的时候执行有参数的构造函数??,这就要看@Autowired注解了!```
  • @Autowired注解

首先看下@Component

在类级别上添加了@Component注解,Spring在启动时就会找到该类(spring采用基于注解和类路径扫描的方式时),并为其生成一个实例,然后,纳入spring容器进行管理。

举例 1 :

参见:@Component @Bean @Configuration 用法

举例 2 :

代码如下(springboot项目):

package com.xl.test.logtest.annotation;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class AutowiredTest {@Autowired(required=false)public AutowiredTest(Desk dk) {System.out.println("==================第一个@Autowired构造器执行================");System.out.println("==================dk================"+dk);}public AutowiredTest() {System.out.println("==================无参构造函数================");}//	@Autowired(required=false)
//	public AutowiredTest(Desk dk, Bench bh) {
//		System.out.println("==================第二个@Autowired构造器执行================");
//	}}@Component
class Desk {}@Component
class Bench {}

如上,类Desk上加上了注解Component, 在类AutowiredTest 中就可自动注入Desk的实例 dk:
在这里插入图片描述
启动项目,验证:
在这里插入图片描述
当然,这个实例是spring通过调用Desk的默认的无参构造器(也是当前唯一的一个构造器)生成的

验证是否调用的是默认构造器

在AutowiredTest中显示的声明无参/默认构造函数以及两个有参数的构造函数:

package com.xl.test.logtest.annotation;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class AutowiredTest {
//	@Autowired(required=false)public AutowiredTest(Desk dk) {System.out.println("==================第一个@Autowired构造器执行================");System.out.println("==================dk================"+dk);}public AutowiredTest() {System.out.println("==================无参构造函数================");}//	@Autowired(required=false)public AutowiredTest(Desk dk, Bench bh) {System.out.println("==================第二个@Autowired构造器执行================");}}@Component
class Desk {}@Component
class Bench {}

启动项目,验证:只执行了默认的构造函数,其余两个并未执行
在这里插入图片描述

如何,在启动的时候执行有参数的构造函数??,这就要看@Autowired注解了!

@Autowired注解

  • 官方解释https://docs.spring.io/spring-framework/docs/5.2.0.M1/javadoc-api/
    在这里插入图片描述
Marks a constructor, field, setter method, or config method as to be autowired by Spring's dependency injection facilities

将构造器、域、setter方法或者配置方法标记为被注入的对象,也就是@Autowired注解可以用于构造器、域、setter方法或者配置方法上。当然,是通过Spring的依赖注入机制来完成依赖注入的。

根据官方文档,@Autowired注解分别对构造器、域、方法、参数等等做了详细解释,这里仅讨论构造器:

Only one constructor (at max) of any given bean class may declare this annotation with the 'required' parameter set to 
true, indicating the constructor to autowire when used as a Spring bean. If multiple non-required constructors declare 
the annotation, they will be considered as candidates for autowiring. The constructor with the greatest number of 
dependencies that can be satisfied by matching beans in the Spring container will be chosen. If none of the candidates 
can be satisfied, then a primary/default constructor (if present) will be used. If a class only declares a single constructor 
to begin with, it will always be used, even if not annotated. An annotated constructor does not have to be public.

当一个类是作为Spring的bean管理时,并且@Autowired的属性required为true(默认值)时,这个类的只能有一个构造函数能使用@Autowired注解: 那么,在启动项目时,会执行该构造器同时Spring会注入该构造器的参数实例(或者称为 依赖 ),如下所示:

package com.xl.test.logtest.annotation;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class AutowiredTest {@Autowiredpublic AutowiredTest(Desk dk) {System.out.println("==================第一个@Autowired构造器执行================");System.out.println("==================dk================"+dk);}public AutowiredTest() {System.out.println("==================无参构造函数================");}//	@Autowiredpublic AutowiredTest(Desk dk, Bench bh) {System.out.println("==================第二个@Autowired构造器执行================");}}@Component
class Desk {}@Component
class Bench {}

启动项目,控制台打印如下:
在这里插入图片描述
延伸: 如果构造器中的参数实例(依赖)也就是 public AutowiredTest(Desk dk) 中的 dk为null(即是:Spring没有初始化并管理Desk的bean (dk) ),那么启动时会报错,如下:
将类Desk的注解@Component去掉:Spring就不会初始化Desk的实例了,其他的保持不变

package com.xl.test.logtest.annotation;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class AutowiredTest {@Autowiredpublic AutowiredTest(Desk dk) {System.out.println("==================第一个@Autowired构造器执行================");System.out.println("==================dk================"+dk);}public AutowiredTest() {System.out.println("==================无参构造函数================");}//	@Autowiredpublic AutowiredTest(Desk dk, Bench bh) {System.out.println("==================第二个@Autowired构造器执行================");}}//@Component
class Desk {}@Component
class Bench {}

启动报错如下:
在这里插入图片描述
解决办法:
1、如上图
2、更改@Autowired的属性required的默认值,将其设置为false
true:默认值,表示所需要的依赖必须存在
false:表示所需依赖可以不存在,但是不会执行该构造器,转而执行默认的构造器(需显示的声明默认构造器,否则,还是会报错:找不到Desk的bean),如下:

Description:Parameter 0 of constructor in com.xl.test.logtest.annotation.AutowiredTest required a bean of type 
'com.xl.test.logtest.annotation.Desk' that could not be found.

验证如下:

package com.xl.test.logtest.annotation;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class AutowiredTest {@Autowired(required=false)public AutowiredTest(Desk dk) {System.out.println("==================第一个@Autowired构造器执行================");System.out.println("==================dk================"+dk);}public AutowiredTest() {System.out.println("==================无参构造函数================");}//	@Autowiredpublic AutowiredTest(Desk dk, Bench bh) {System.out.println("==================第二个@Autowired构造器执行================");}}//@Component
class Desk {}@Component
class Bench {}

在这里插入图片描述
此时,项目正常启动,但是,并没有执行@Autowired注解的构造器。

==小结:也就是只有提供了构造器的依赖实例(参数示例),才会执行构造器,那就是说@Autowired注解的属性required=true才有意义,因为required=false,如果有依赖就执行@Autowired注解的构造器; 没有依赖就执行默认的构造器(前提是:显示声明默认构造器!),但是没有执行@Autowired注解的构造器啊 ==

required=false真的没有意义吗? 不是的!,看下官方的文档:

If multiple non-required constructors declare the annotation, they will be considered as candidates for autowiring. The constructor with the greatest number of dependencies that can be satisfied by matching beans in the Spring container will be chosen.

如果有多个构造器的required都为false,那么这些构造器都会作为候选待执行构造器,最终执行哪一个取决于哪个构造器在spring容器中的依赖(参数实例)更多,执行依赖最多的一个构造器;如果所有的构造器的依赖数量都是零,那么就执行默认的构造器!但是,需要显示的声明默认的构造器,如果没有声明则会报错!

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

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

第四章 道德经第四章原文 道德经第四章译文

道德经第四章原文 道冲①,而用之有弗盈也②。渊呵③!似万物之宗④。锉其兑⑤,解其纷⑥,和其光⑦,同其尘⑧。湛呵⑨!似或存⑩。吾不知其谁之子,象帝之先⑾。 道德经第四章译文 大“道”空虚开形…

Swift(2)

因为要在31号之前用swift写一个系统,我不得不把我的电脑系统更新了一下,之后便下载了这个, 做了一些简单的测试,部分软件还是可以打开的。 这个软件用着的确比那个网站用着要舒服很多。 目录 问号 感叹号 ​编辑if else ​编…

“注水”的新力与“错付”的陈凯

“明星职业经理人”陈凯终究还是没迈过三年的坎儿,只是这次“错付”竟只有半年。 能以120万元的“微薄”年薪吸引明星职业经理人的加盟,这个公司并不简单。作为地产界的“黑马”,新力控股集团有限公司(HK:02103)几年时间实现了业绩突飞猛进&…

基于tushare的股票数据构建1

基于tushare的股票数据构建<一> tushare中提供了很多非常优秀的数据结构&#xff0c;但是并不是所有的数据都对自己有用&#xff0c;这里需要进行构建自己的数据库以方便后续进行数据建模 tushare数据 tushare是完全免费的一个数据源&#xff0c;不只是有股票数据&…

诺泰生物更新IPO招股书:少数股东权益亏损,信息披露违规不断

3月10日&#xff0c;贝多财经发现&#xff0c;经上市委会议通过后&#xff0c;江苏诺泰澳赛诺生物制药股份有限公司&#xff08;下称简称“诺泰生物”&#xff09;于2021年2月8日在科创板申报了招股书&#xff08;注册稿&#xff09;&#xff0c;更新了2020年度的财务资料。 据…

【开源】开源项目推荐

一、虾婆 开源即时通讯解决方案 http://xiaper.io/xiaper.io/ 二、 待补充

虾婆一企业级开源即时通讯解决方案

什么是虾婆&#xff1f; 虾婆是一企业级开源即时通讯解决方案。包含服务器端和客户端&#xff0c;其中客户端支持Web/H5、安卓、iOS、Windows、Mac、微信公众号、小程序等。服务器端开发语言Java&#xff0c;基于SpringBoot2开发&#xff0c;支持SpringCloud微服务架构&#x…

Linux从零开始到入坑

一、服务相关命令 1.启动服务&#xff1a;systemctl start 服务名称&#xff1b; 2.重启服务&#xff1a;systemctl restart 服务名称&#xff1b; 3.停止服务&#xff1a;systemctl stop 服务名称&#xff1b; 4.查看服务状态&#xff1a;systemctl status 服务名称&#…