实现方法、构造器位置的自动装配

news2025/1/14 0:55:44

1.@Autowired注解概述

@Autowired注解的源码

package org.springframework.beans.factory.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

    boolean required() default true;
}

@Autowired注解的源码可以看出,在@Autowired注解上标注有如下的注解信息:

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})

可以看出@Autowired注解不仅可以标注在字段上,而且还可以标注在构造方法、实例方法以及参数上

2.实战案例

2.1.案例准备

在项目中新建一个Boss类,在Boss类中有一个Car类的引用,使用@Component注解将Dog类加载到IOC容器中,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {
    
    private Car car;
    
    @Override
      public String toString() {
          return "Boss [car=" + car + "]";
    }
}
package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Car类
 * @author liqb
 * @date 2023-04-27 11:43
 **/
@Data
@Component
public class Car implements Serializable {

    public Car() {
        System.out.println("car constructor...");
    }

    public void init() {
        System.out.println("car ... init...");
    }

    public void destroy() {
        System.out.println("car ... destroy...");
    }
}

新建好以上Boss类之后,在MainConfigOfAutowired配置类的@ComponentScan注解中进行配置,使其能够扫描com.tianxia.springannotation.entity包下的类,如下所示

package com.tianxia.springannotation.config;

import com.tianxia.springannotation.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * 配置类
 * @author liqb
 * @date 2023-05-06 13:11
 **/
@Configuration
@ComponentScan({
        "com.tianxia.springannotation.service", 
        "com.tianxia.springannotation.dao", 
        "com.tianxia.springannotation.controller",
        "com.tianxia.springannotation.entity"
})
public class MainConfigOfAutowired {

    /**
     * 注入bookDao对象
     * @author liqb
     * @date 2023-05-06 13:27
     * @return
     */
    @Primary
    @Bean("bookDao2")
    public BookDao bookDao() {
        BookDao bookDao = new BookDao();
        bookDao.setLable("2");
        return bookDao;
    }
}

2.2.标注在实例方法上

可以将@Autowired注解标注在setter方法上,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    @Autowired
    public void setCar(Car car) {
        this.car = car;
    }
    
    @Override
      public String toString() {
          return "Boss [car=" + car + "]";
      }
}

当@Autowired注解标注在方法上时,Spring容器在创建当前对象的时候,就会调用相应的方法为对象赋值。如果标注的方法存在参数时,那么方法使用的参数和自定义类型的值,需要从IOC容器中获取。

运行测试方法,输出的结果信息如下所示::

/**
 * 测试方法
 * @author liqb
 * @date 2023-05-08 11:51
 */
@Test
public void test02() {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

    Boss boss = applicationContext.getBean(Boss.class);
    System.out.println(boss);
    
    Car car = applicationContext.getBean(Car.class);
    System.out.println(car);

    applicationContext.close();
}

在这里插入图片描述

说明已经获取到了car的信息,也就是说可以将@Autowired注解标注在方法上

2.3.标注在构造方法上

为Boss类添加一个有参构造方法,然后去除setCar()方法上的@Autowired注解,将@Autowired注解标注在有参构造方法上,并在构造方法中打印一条信息,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    @Autowired
    public Boss(Car car) {
        this.car = car;
        System.out.println("Boss...有参构造器");
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss [car=" + car + "]";
    }
}

运行上述测试方法,输出的结果信息如下所示::

在这里插入图片描述

使用@Autowired注解标注在构造方法上时,构造方法中的参数对象也是从IOC容器中获取的

使用@Autowired注解标注在构造方法上时,如果组件中只有一个有参构造方法,那么这个有参构造方法上的@Autowired注解可以省略,并且参数位置的组件还是可以自动从IOC容器中获取

2.4.标注在参数上

可以将@Autowired注解标注在参数上,例如,在Boss类中我们将构造方法上的@Autowired注解标注在构造方法的参数上,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    public Boss(@Autowired Car car) {
        this.car = car;
        System.out.println("Boss...有参构造器");
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss [car=" + car + "]";
    }
}

可以将@Autowired注解标注在setter方法的参数上,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Boss类
 * @author liqb
 * @date 2023-05-08 11:33
 **/
@Data
@Component
public class Boss implements Serializable {

    private Car car;

    public Car getCar() {
        return car;
    }

    public void setCar(@Autowired Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Boss [car=" + car + "]";
    }
}

最终的效果与标注在字段、实例方法和构造方法上的效果都是一样的

得出结论:无论@Autowired注解是标注在字段上、实例方法上、构造方法上还是参数上,参数位置的组件都是从IOC容器中获取

2.5.标注在方法位置

@Autowired注解可以标注在某个方法的位置上。新建一个Color类,在Color类中有一个Car类型的成员变量,如下所示:

package com.tianxia.springannotation.entity;

import lombok.Data;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * 颜色类
 * @author liqb
 * @date 2023-04-23 15:35
 **/
@Data
@Component
public class Color implements Serializable {

    public Car car;

    @Override
    public String toString() {
        return "Color [car=" + car + "]";
    }
}

在MainConfigOfAutowired配置类中实例化Color类,如下所示:

@Bean
public Color color(@Autowired Car car) {
    Color color = new Color();
    color.setCar(car);
    return color;
}

@Bean
public Color color02(Car car) {
    Color color = new Color();
    color.setCar(car);
    return color;
}

运行测试方法,输出的结果信息如下所示:

/**
 * 测试方法
 * @author liqb
 * @date 2023-05-08 11:51
 */
@Test
public void test03() {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

    Color color = applicationContext.getBean(Color.class);
    System.out.println(color);

    applicationContext.close();
}

在这里插入图片描述

说明Car对象被成功创建并设置到Color对象中了


至此,我们可以得出结论:如果方法只有一个IOC容器中的对象作为参数,当@Autowired注解标注在这个方法的参数上时,可以将@Autowired注解省略掉。也就说@Bean注解标注的方法在创建对象的时候,方法参数的值是从IOC容器中获取的,此外,标注在这个方法的参数上的@Autowired注解可以省略。

用到最多的还是把@Autowired注解标注在方法位置,即使用@Bean注解+方法参数这种形式,此时,该方法参数的值从IOC容器中获取,并且还可以默认不写@Autowired注解,因为效果都是一样的,都能实现自动装配!

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

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

相关文章

Uint8Array文件下载

vue项目,自己调用了阿里云OSS的SDK,进行文件的上传以及下载,有个功能是列表中的附件需要支持点击下载,这里就用到阿里云oss的文件下载,使用了Nodejs的SDK const OSS require(ali-oss); const client new OSS({...op…

nodejs+vue网上学生社团管理系统

并运用Photoshop CS6技术美化网页,辅之以CSS技术。系统是基于面向对象编程的web应用程序。本系统主要实现的功能有系统用户管理、社团信息管理、社团类别管理、社团活动管理、社团论坛管理、系统管理、个人资料管理、学生入团管理、社团公告管理、社团活动管理、社团…

Ubuntu22.04安装opencv依赖包libjasper-dev出现unable to locate libjasper-dev的终极解决办法

执行 sudo apt install libjasper-dev 提示 执行 sudo apt install libjasper1 libjasper-dev 仍然提示 更换软件源: sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main" sudo apt-get update提示 该仓库没有数…

tiechui_lesson05_内核小文件拷贝

主要学习在内核中的文件操作,包括文件的打开,创建,读取,写入,查询文件属性等。 涉及的API和宏函数 ZwOpenFileZwCreateFileZwQueryInformationFileZwReadFileZwWriteFileZwCloseInitializeObjectAttributes 1.文件的…

学习日记,java学习

题目 生病了,可能是羊了,喉咙好干,好难受 每日一题 1010. 总持续时间可被 60 整除的歌曲 难度中等268收藏分享切换为英文接收动态反馈 在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒。 返回其总持续时间(以秒为单位)可被 60 整除的…

vue+elementui在线教学互动学习考试系统nodejs师生互动交流网站kpm58

语言 node.js 框架:Express 前端:Vue.js 数据库:mysql 数据库工具:Navicat 开发软件:VScode 前端vueelementui, (1) vue引入elementui 1.使用npm安装element-ui npm i element-ui -S 2.在main.js中导入使用vue import element-u…

Android WorldWind的使用与加载数方瓦片

明确下定义,数方瓦片也叫五层十五级瓦片。现记录下如何在World Wind Android中加载数方瓦片的方法。 原理 加载数方瓦片最核心的方法是WorldWindAndroid加载图片的方法,更加详细的使用说明请访问worldwind官网。核心代码如下: Sector sect…

Daimayuan Online Judge #613. 好序列(思维题 暴力/启发式分裂)

题目 思路来源 知乎严格鸽 (暴力/启发式分裂)代码源每日一题 Div1 好序列 - 知乎 题解 启发式分裂,可以认为是启发式合并的逆过程 比较直白的想法是找到第一个只出现一次的数的位置x,然后分治[1,x-1]和[x1,n] 但是这样最坏复杂度是O(n^2)的&#xf…

数字化转型对企业的好处有哪些(上)

过时的技术、流程和客户关系管理困难是当前阻碍企业增长的主要障碍,CRM系统是企业数字化转型的主要工具,帮助企业简化操作、提高效率,为客户提供更加卓越的客户体验。下面说说,企业数字化转型的十大好处。 放眼全球来看&#xff…

第四十三章 Unity 开关 (Toggle) UI

本章节我们介绍开关 (Toggle)和开关组 (Toggle Group)。首先,我们点击菜单栏“GameObject”->“UI”->“Toggle”,然后调整它的位置,效果如下所示 相信大家在很多网页中也看到过类似的UI元素,它通常用于让用户勾选某些选项。…

计算机二级精选习题精讲精练

请点击↑关注、收藏,本博客免费为你获取精彩知识分享!有惊喜哟!! 1、在线性表的链式存储结构中,其存储空间一般是不连续的,并且( ) A)前件结点的存储序号大于后件结点的存储序号 B&#x…

java排序算法精讲

排序算法 概要一、冒泡排序概念实现步骤 代码 二、选择排序概念实现步骤 代码 三、插入排序概念实现步骤 代码 四、快速排序概念实现步骤 代码 五、归并排序概念实现步骤 代码 六、堆排序概念实现步骤 代码 总结以二维表表现出各个排序的关系 概要 Java是一种面向对象的编程语言…

一篇文章带您区分GNSS欺骗模拟测试的两种方式

写在前面 注意:提供的设备与案例、使用指南等指导性文件是为了在测试环境中对接收机的抗干扰能力进行验证,而非出于欺骗或干扰真实环境中的GNSS信号的目的!请确保通过线缆连接应用或暗室应用,若因为违规使用产生的任何法律后果和…

携带数据的Ajax POST请求

前端页面代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>发送ajax POST请求 看如何携带数据</title> <script type"text/javascript"> …

MES管理系统有什么功能?前期实施MES需要做些什么

MES系统是在制造业数字化的环境下&#xff0c;围绕生产制造执行而开发的一套生产管理系统。它以车间为管理核心&#xff0c;通过集成各信息系统&#xff0c;整合企业资源&#xff0c;实现从订单下达到产品完成的整个生产制造过程的数字化管理。 MES系统在实施前需要进行各种准备…

“UTONMOS吧”的出现,能否唤起百度贴吧曾经的辉煌?

百度贴吧&#xff0c;诞生于一个中文互联网尚且信息不足的时代&#xff0c;并建立起了一个庞大的社区。然而进入自媒体时代&#xff0c;贴吧这个大广场日渐冷清&#xff0c;2015年月活用户超过3亿&#xff0c;到2021年已不足4000万。 梗的流行&#xff0c;带动一大批人开始网上…

OpenShift 4 - KubeVirt 虚机使用的磁盘和卷

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.12 环境中验证 文章目录 KubeVirt 虚机的磁盘和卷Disk 磁盘Volume 卷 磁盘和卷示例containerDisk 卷示例cloudInitNoCloud 卷示例dataVolume 卷示例基于容器镜像基于 qcow2 文件基于 DataSo…

放大招:三步搞定ChatGPT提示词,轻松写出高质量提问,最新经验分享

在撰写ChatGPT提示语的时候&#xff0c;有一个基本的三层结构&#xff0c;经过在工作和生活上的实践&#xff0c;有助于解决大多数不同类型的任务。 尤其在你的问题有点复杂&#xff0c;想不清楚要怎么问比较好的时候&#xff0c;通过三层结构&#xff0c;让我们有结构的提出问…

力扣简单题

目录 9、回文数 13、罗马数字转整数 14、最长公共前缀 20、有效的括号 58、最后一个单词的长度 66、加一 69、x的平方根 94、二叉树的中序遍历 100、相同的树 202、快乐数 205、同构字符串 242、有效的字母异位词 258、各位相加 268、丢失的数字 290、单词…

Github 使用教学

&#x1f4ad; 写在前面&#xff1a;本章我们将介绍 Git 的基本使用方法&#xff0c;包括注册 GitHub 账号、设置 Git、创建本地存储库、复制本地存储库、导入远程存储库、追加、提交、合并等常用操作。我们还会教你如何在 GitHub 上创建项目&#xff0c;使用 git clone 命令克…