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容器中的依赖(参数实例)更多,执行依赖最多的一个构造器;如果所有的构造器的依赖数量都是零,那么就执行默认的构造器!但是,需要显示的声明默认的构造器,如果没有声明则会报错!

Spring @Autowired 用法相关推荐

  1. spring @Autowired用法

    首先要知道另一个东西,default-autowire,它是在xml文件中进行配置的,可以设置为 byName.byType.constructor 和 autodetect. 比如byName,不用 ...

  2. spring autowired idea都匹配上了_你清楚这几个Spring常用注解吗?

    作者:平凡希http://cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 如 ...

  3. Spring @Autowired 注释

    转载自  Spring @Autowired 注释 Spring @Autowired 注释 @Autowired 注释对在哪里和如何完成自动连接提供了更多的细微的控制. @Autowired 注释可 ...

  4. Spring @Autowired Annotation教程

    Spring @Autowired Annotation教程 Spring @Autowired注释用于自动依赖注入.Spring框架是基于依赖注入构建的,我们通过spring bean配置文件注入类 ...

  5. Spring @Autowired Annotation

    Spring @Autowired Annotation Spring @Autowired注释用于自动依赖注入.Spring框架是基于依赖注入构建的,我们通过spring bean配置文件注入类依赖 ...

  6. Spring @Autowired批注

    Spring @Autowired annotation is used for automatic dependency injection. Spring framework is built o ...

  7. Spring @Autowired、@Resource、@Required、@Component、@Repository、@Service、@Controller注解的用法和作用...

    Spring @Autowired,@Resource,@Required注解的用法和作用 Spring中 @Autowired标签与 @Resource标签 的区别 Spring注解@Compone ...

  8. Spring AOP用法

    软件152 杨浩艺 Spring AOP Java web 环境搭建 Java web 项目搭建 Java Spring IOC用法 spring提供了两个核心功能,一个是IoC(控制反转),另外一个 ...

  9. 使用Spring @Autowired List的责任链

    在Spring 3.1中,有一种方法可以自动填充类型化的List,这在您想在代码中稍微进行去耦和清理时非常方便. 为了向您展示它是如何工作的,我将实现一个简单的责任链,该责任链将为通过的用户打印一些问 ...

最新文章

  1. SQL语句-exec执行
  2. 研究生数学建模比赛日程安排
  3. C语言中文网js,第一个JavaScript程序
  4. C#中将字符串内容写入到txt文件中
  5. 玩游戏老显示计算机内存不足,windows8.1玩游戏经常提示内存不足
  6. koa --- 自制简易的koa-router
  7. WordPress主题-果核剥壳站长开发CorePress v2.6
  8. bootstrap-datepicker实现日期input readonly 标签中选择时间功能
  9. 基于better-scroll实现的类似ios选择器
  10. 每日算法系列【LeetCode 312】戳气球
  11. 发现同构:Gartner曲线、达克效应 与 跨越鸿沟
  12. 用Scratch制作手游的角色方向虚拟控制器/虚拟摇杆的方法+源码
  13. AttnGAN代码复现(详细步骤+避坑指南)文本生成图像
  14. unity 制作行李箱密码
  15. 生活用电安全常识:零线与地线的区别!
  16. Cortana与应用程序的后台交互
  17. 1.6 建立Servers服务(2020-12-6)
  18. stripped 和 not stripped
  19. 初级程序员与高级程序员
  20. hinge_在Swift中在iOS上重新创建Hinge的配置文件过渡

热门文章

  1. 数据库性能测试-mysql篇
  2. Python爬虫网易云歌词及词频统计--(周杰伦top50)
  3. 计算机和通讯技术对我们生活的改变,信息技术的发展,带来了哪些方面的改变?...
  4. SMTP;ESMTP
  5. 单片机笔记十一:华大单片机
  6. 三菱PLC之间的N:N无线通讯的常见问题汇总【1】
  7. Windows环境下安装PyMySQL(已安装Anaconda)
  8. 使用NanoHttpd在Android上实现HttpServer
  9. 工具篇 之 iTerm 2 用户名修改(基于 iTerm 2 + oh-my-zsh)
  10. 【linux】内核模块管理:lsmod、insmod、rmmod、modinfo、modprobe、depmod命令