Spring @Autowired 用法

news2024/9/25 23:25:29

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 {
	@Autowired
	public AutowiredTest(Desk dk) {
		System.out.println("==================第一个@Autowired构造器执行================");
		System.out.println("==================dk================"+dk);
	}
	
	public AutowiredTest() {
		System.out.println("==================无参构造函数================");
	}
	
//	@Autowired
	public 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 {
	@Autowired
	public AutowiredTest(Desk dk) {
		System.out.println("==================第一个@Autowired构造器执行================");
		System.out.println("==================dk================"+dk);
	}
	
	public AutowiredTest() {
		System.out.println("==================无参构造函数================");
	}
	
//	@Autowired
	public 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("==================无参构造函数================");
	}
	
//	@Autowired
	public 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.coloradmin.cn/o/170564.html

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

相关文章

Flask入门教程(视频教程笔记)

初始化flask项目 前面的python环境之类的就不说了。 该博客是看 Flask 入门 这个视频教程写的笔记,如果你想入门一下Flask,可以看看这个课,虽然简短,但是入门部分讲的很好,同时可以利用这篇博客复习复习。如果你想了解…

二、MES的生态链

1、MES功能模块图1、 符合MESA/ISA-95标准,基于SOA架构,技术架构与业务架构分离,实现多厂分布式部署具备标准化模型组件,可根据客户需求选取标准组件、或调整业务对象脚本,组合成全新的业务组件,实现企业ME…

电动汽车热管理方案

热管理技术作为汽车节能、提高经济性和保障安全性的重要措施,在汽车研发过程中具有重要作用。传统燃油汽车的热管理系统主要包括发动机、变速器散热系统和汽车空调,而电动汽车的热管理系统在燃油汽车热管理架构的基础之上,又增加了电机电控热…

【Python百日进阶-数据分析】Day228 - plotly的图表的变换

文章目录一、过滤二、分组三、聚合四、多重转换4.1 Filter and Group By4.2 Filter and Aggregate4.3 所有变换4.4 Dash中的应用一、过滤 如何通过 Plotly 在 Python 中使用过滤器。 注意 transforms在 v5 中已弃用,plotly将在未来版本中删除 import plotly.io as…

分享97个PHP源码,总有一款适合您

PHP源码 分享97个PHP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 97个PHP源码下载链接:https://pan.baidu.com/s/1OUa-rpzDK6CG8oj6BLZSTw?pwdxdt2 提取码&#xff…

上传ipa到appstore的步骤说明

上传ipa到appstore,首先你要有苹果开发者账号,一定要使用你自己的苹果开发者账号的证书打包,才能将ipa上传到你自己的苹果账号,才能提交到app store里。假如你还没有苹果开发者账号,或者你有证书但不是你自己账号生成的…

ES6ES6

ES8-ES8 新特性 4.1.async 和 await async和await 两种语法结合可以让异步代码像同步代码一样 4.1.1.async函数 async函数的返回值为 promise 对象, 2.promise 对象的结果由 asynt函数执行的返回值决定 4.1.2await表达式awaity必须写在 async 函数中 2.await 右侧…

Rockchip开发系列 - 3.2.引脚配置默认上拉下拉

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 返回总目录:Rockchip开发系列 - 总目录 开发过程中发现rk3568-linux.dtsi中耳机监测应急一直是处于低电平状态: 这个gpio表格也说…

【MyBatis】| 在WEB中应⽤MyBatis(使⽤MVC架构模式)

目录 一:在WEB中应⽤MyBatis(使⽤MVC架构模式) 1. 前期准备 2. 核心代码实现 3. 事务控制 4. 三大对象的作用域 一:在WEB中应⽤MyBatis(使⽤MVC架构模式) 目标: ①掌握mybatis在web应⽤中怎…

【闪电侠学netty】第9章 实现客户端登录

【Netty】读书笔记 - 跟闪电侠学 1. 内容概要 1.1 总结 1.1.1 逻辑处理器 ChannelHandler(详见 第11章 Pipeline与ChannelHandler) 1.1.2 编程小技巧 public class PacketCodeC {...public static final PacketCodeC INSTANCE new PacketCodeC();.…

spring学习-第一讲-beanFactory与ApplicationContext

BeanFactory与ApplicationContext区别 创建一个springboot项目,对这个函数的main函数来进行执行。 ConfigurableApplicationContext context SpringApplication.run(BeanFactoryApplicationContextStudyApplication.class, args); 很明显,Configurabl…

“互联网+”六年,云徙科技打造数字化经营增长“头牌”

2022年底的全面开放结束了三年疫情,三年来以消费零售为代表的商业领域发生了深刻变局。根据2022年8月的第50次中国互联网络发展状况统计报告,互联网推动网民消费模式变迁:在消费场景方面,从线上消费逐步转变为线上线下融合消费&am…

软件安装教程-Vivado2018.3/ISE14.7/Modelsim10.5/Keil5/AD18/Cadence17.2/CAD2016

硬件工程师软件安装教程 1.Vivado2018.3安装教程 本文的主要内容是介绍 Vivado 2018.3 版本(提取码:ebdx)的安装步骤及其 license(提取码: 6xkh) 的获取与加载。 本文学习自《【ALINX】FPGA ZYNQ视频教程——AX7010/AX7020教程——基础部分》 首先下载安装包&…

【Unity3D】基于模板测试和顶点膨胀的描边方法

1 前言 选中物体描边特效 中介绍了基于模板纹理模糊膨胀的描边方法,该方法实现了软描边,效果较好,但是为了得到模糊纹理,对屏幕像素进行了多次二次渲染,效率欠佳。本文将介绍另一种描边方法:基于模板测试和…

简单使用tomcat查看版本信息等·

Tomcat 是什么 ?1.Apache Tomcat 是由 Apache Software Foundation(ASF)开发的一个开源 Java WEB 应用服务器。2.由于 Tomcat 是由 Java 语言实现的,因此需要运行在 Java 虚拟机上,所以使用前要先安装 JDK,…

JNPF Java3.4.5 .NET6 3.4.5 框架源码 JeeSite快速开发平台

JeeSite JeeSite 快速开发平台的主要目的是能够让初级的研发人员快速的开发出复杂的业务功能,中高级人员有时间做一些更有用的事情。让开发者注重专注业务,其余有平台来封装技术细节,降低技术难度,从而节省人力成本,缩…

电商控价,为什么要找控价公司

刚刚做控价的时候,相信我们心中都有一个疑问:控价嘛,很简单,把标准价格发给低价店铺,让他调价不就行了?不配合,我就投诉,要么我就断货,自己产品自己说了还不算吗&#xf…

《大话数据结构》读书笔记---第一章 数据结构绪论

数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间关系和操作等相关问题的学科。程序设计数据结构算法数据:是描述客观事物的符号,是计算机中可…

C++复数类——运算符重载和类的传递

复数:我们把形如abi(a,b均为实数)的数称为复数,其中a称为实部,b称为虚部,i称为虚数单位。当虚部等于零时,这个复数可以视为实数;当z的虚部不等于零时,实部等于零时&#…

【Kotlin】类的继承 ② ( 使用 is 运算符进行类型检测 | 使用 as 运算符进行类型转换 | 智能类型转换 | Any 超类 )

文章目录一、使用 is 运算符进行类型检测二、使用 as 运算符进行类型转换 ( 智能类型转换 )三、Any 超类一、使用 is 运算符进行类型检测 在 Kotlin 中 , 如果不确定一个 实例对象的类型 , 可以 使用 is 运算符进行判定 , 使用方法 实例对象 is 判定类型上述用法可以判定 实例…