5.自动装配:autowire=“byName“ or “byType“ + 使用注解【@Autowired 、@Qualifier、 @Resource】

2023-11-04

自动装配说明

Spring的自动装配需要从两个角度来实现,或者说是两个操作:

  1. 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
  2. 自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的DI;

组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少

推荐不使用自动装配xml配置 , 而使用注解 .



本博客环境搭建

1、新建一个module项目

在这里插入图片描述

2、新建两个实体类,Cat Dog 都有一个叫的方法

public class Cat {
   public void shout() {
       System.out.println("miao~");
  }
}
public class Dog {
   public void shout() {
       System.out.println("wang~");
  }
}

3、新建一个用户类 People

@Data
public class People {
    private Cat cat;
    private Dog dog;
    private String str;
}

4、编写Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="dog" class="com.kuang.pojo.Dog"/>
   <bean id="cat" class="com.kuang.pojo.Cat"/>

   <bean id="user" class="com.kuang.pojo.User">
       <property name="cat" ref="cat"/>
       <property name="dog" ref="dog"/>
       <property name="str" value="qinjiang"/>
   </bean>
</beans>

5、测试

public class MyTest {
   @Test
   public void testMethodAutowire() {
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       User user = (User) context.getBean("user");
       user.getCat().shout();
       user.getDog().shout();
  }
}

在这里插入图片描述
结果正常输出,环境OK



自动装配

需要pom依赖:spring-aop
在这里插入图片描述

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.7.RELEASE</version>
</dependency>

autowire=“byName”(按名称自动装配)

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。

采用自动装配将避免这些错误,并且使配置简单化。

测试:

1、修改bean配置,增加一个属性 autowire=“byName”

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>

<bean id="user" class="com.kuang.pojo.User" autowire="byName">
   <property name="str" value="qinjiang"/>
</bean>

2、再次测试,结果依旧成功输出!

3、我们将 cat 的bean id修改为 catXXX

4、再次测试, 执行时报空指针java.lang.NullPointerException。因为按byName规则找不对应set方法,真正的setCat就没执行,对象就没有初始化,所以调用时就会报空指针错误。

小结:

当一个bean节点带有 autowire byName的属性时:

  1. 将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。

  2. 去spring容器中寻找是否有此字符串名称id的对象。

  3. 如果有,就取出注入;如果没有,就报空指针异常。



autowire=“byType” (按类型自动装配)

使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一异常:NoUniqueBeanDefinitionException

测试:

1、将user的bean配置修改一下 : autowire="byType"

2、测试,正常输出

3、再注册一个cat 的bean对象!

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

<bean id="user" class="com.kuang.pojo.User" autowire="byType">
   <property name="str" value="qinjiang"/>
</bean>

4、测试,报错:NoUniqueBeanDefinitionException

5、删掉cat2,将cat的bean名称改掉!测试!因为是按类型装配,所以并不会报异常,也不影响最后的结果。甚至将id属性去掉,也不影响结果

这就是按照类型自动装配!



使用注解

jdk1.5开始支持注解,spring2.5开始全面支持注解。

准备工作:利用注解的方式注入属性。

1、在spring配置文件中引入context文件头

xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

2、开启属性注解支持!

方式一:
<!--配置扫描哪些包下的注解-->
<context:component-scan base-package="com.kuang.pojo"/>


方式二:【不推荐,因为方式一包含方式二的注解,还包含其他的】
<context:annotation-config/>

在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>
    

</beans>



1. @Autowired(按类型自动转配的,不支持id匹配)

  • @Autowired是按类型自动转配的,不支持id匹配。
  • 需要导入 spring-aop的包!

测试:

1、将People类中set方法可去掉,使用@Autowired注解

@Data
public class People {
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
    private String str;
}

2、此时配置文件内容

<context:annotation-config/>

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="people" class="com.kuang.pojo.People"/>

3、测试,成功输出结果!

@Test
public void testMethodAutowire() {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    People user = (People) context.getBean("people");
    user.getCat().shout();
    user.getDog().shout();
}

在这里插入图片描述

4、补充点

@Autowired(required=false) 说明:
false,对象可以为null;
true,对象必须存对象,不能为null。

//如果允许对象为null,设置required = false,默认为true
@Autowired(required = false)
private Cat cat;


对象可以为空的另一种方式:
public People(@Nullable String name){
      this.name=name;
}



2. @Qualifier(不能单独使用,加上@Qualifier则可以根据byName的方式自动装配)

  • @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
  • @Qualifier不能单独使用。

测试实验步骤:

1、配置文件修改内容,保证类型存在对象。且名字不为类的默认名字!

<context:annotation-config/>

<bean id="dog1" class="com.kuang.pojo.Dog"/>
<bean id="dog2" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

<bean id="people" class="com.kuang.pojo.People"/>

2、没有加Qualifier测试,直接报错

3、在属性上添加Qualifier注解

@Autowired使用事项:两个同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一异常
所以搭配@Qualifier解决这个问题

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

测试,成功输出!



3. @Resource(先进行byName查找,失败;再进行byType查找)

  • @Resource如有指定的name属性,先按该属性进行byName方式查找装配;
  • 其次再进行默认的byName方式进行装配;
  • 如果以上都不成功,则按byType的方式自动装配。
  • 都不成功,则报异常。

实体类:

public class User {
   //如果允许对象为null,设置required = false,默认为true
   @Resource(name = "cat2")
   private Cat cat;
   @Resource
   private Dog dog;
   private String str;
}

beans.xml

<context:annotation-config/>

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

<bean id="people" class="com.kuang.pojo.People"/>

测试:结果OK

配置文件2:beans.xml , 删掉cat2

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>

实体类上只保留注解

@Resource
private Cat cat;
@Resource
private Dog dog;

结果:OK

结论:先进行byName查找,失败;再进行byType查找,成功。



4. @Autowired与@Resource异同

1、@Autowired@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。

2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false),如果我们想使用名称装配可以结合@Qualifier注解进行使用

3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

5.自动装配:autowire=“byName“ or “byType“ + 使用注解【@Autowired 、@Qualifier、 @Resource】 的相关文章

随机推荐

  • 学习cocos2d-x 之路 (1)--了解cocos2d-x

    学前感言 很久以前就听说过cocos2d的大名 知道它在手机游戏开发中处于主导地位 但是今天是真正意义上第一次接触 当前手机游戏市场十分火爆 我想对于任何一个对游戏感兴趣并且准备投身手机游戏开发的人学习这款引擎都是必要的 从百度百科上阅读了
  • Linux学习之安装vim软件

    Linux学习之安装vim软件欢迎来到陈冬冬的个人经验分享平台https www chendd cn blog article 1477573897833009153 html 在前一篇文章中初步使用到了 vi 命令去更改网络连接的参数文件
  • 【git系列】从远端仓库获取最新代码合并到本地分支里

    在日常开发中 很有可能几个开发人员都在开发同一个代码仓分支 导致本地分支里的代码 落后于 远端分支里的 我们需要做的就是从远端仓库获取最新代码合并到本地分支里 1 git pull 有风险 获取最新代码到本地 并自动合并到当前分支 首先我们
  • ORB_SLAM2 with XTION的编译问题(1)

    ORB SLAM2 with XTION的编译问题及解决 1 源链接为https github com chaizheng2157 RGBD ORB SLAM2 RT 其中里面有两个包要编译 分别是g2o with orbslam2和ORB
  • matlab做多元门限回归模型,门限自回归模型

    2014年第6期 郑晓亚 我国股权风险溢价的长期趋势与短期特征 我国股权风险溢价的长期趋势与短期特征 结合门限自回归模型与B P多重结构型断点检验的经验研究郑 Hansen 于 1996 年在 Econometrica 上发表文章 Infe
  • Vercel国内无法访问解决方案

    域名解析使用 cname vercel dns com 或 将 A 记录从 76 76 21 21 改成 76 223 126 88 官方建议将 cname 从 cname vercel dns com 修改为 cname china ve
  • python web页面增删改查_python web 增删改查教你快速入门

    1 导入需要的扩展和包from sqlalchemy import create engine Column Integer String from sqlalchemy ext declarative import declarative
  • 数据源 JNDI 作用

    数据源在JDBC中的应用简介众所周知 JDBC Java数据库连接 是Java 2企业版的重要组成部分 它是基于SQL层的API 通过把SQL语句嵌入JDBC接口的方法中 用户可以通过Java程序执行几乎所有的数据库操作 JDBC只提供了接
  • uni-app的Vue.js实现微信小程序的紧急事件登记页面功能

    主要功能实现 完成发生时间选择功能 用户可以通过日期选择器选择事件发生的时间 实现事件类型选择功能 用户可以通过下拉选择框选择事件的类型 添加子养殖场编号输入框 用户可以输入与事件相关的子养殖场编号 完成事件描述输入功能 用户可以通过文本输
  • 1、网易校招2016年《下厨房》

    题目描述 牛牛想尝试一些新的料理 每个料理需要一些不同的材料 问完成所有的料理需要准备多少种不同的材料 输入描述 每个输入包含 1 个测试用例 每个测试用例的第 i 行 表示完成第 i 件料理需要哪些材料 各个材料用空格隔开 输入只包含大写
  • 数据分析实战项目:SQL分析淘宝用户行为

    文章目录 一 项目背景及目的 1 1 项目背景 1 2 项目目的 1 3 数据集来源与介绍 二 数据导入 2 1 图形界面工具导入 2 2 以系统命令行导入 三 数据清洗 3 1 删除重复值 3 2 查看缺失值 3 3 时间格式转换 3 4
  • 赛宁网安有力保障淮安市网络安全技能竞赛决赛

    9月6日 由中共淮安市委网信办 淮安市总工会 淮安市人社局 淮安市教育局 淮安市公安局 共青团淮安市委共同主办 淮阴工学院协办 淮安市网络信息和数据安全协会 淮安市信息安全等级保护工作协调小组办公室承办 中国电信股份有限公司淮安分公司 中国
  • stm32 无刷电机控制板

    stm32f103c8t6 做主控 自制无刷电机 bldc 控制板 支持有感和无感两种模式 可通过硬件切换 内部包含原理图和源代码及照片 文件 url80 ctfile com f 25127180 745426979 e8e3fc p 5
  • Acesrc and Hunting【模拟 贪心】

    HDU 6660 题目链接 这道题主要就是讲我们从任意点出发 每次走的都是没走过并且 曼哈顿距离大于1小于3的点 然后问能不能覆盖完整幅图 这里就想到一个很经典的问题 4399小游戏除草游戏 以前玩过的一个小游戏倒是让我对这道题的解法有了方
  • 动手学数据分析 Task4

    动手学数据分析 Task4 一 可视化展示泰坦尼克号数据集中男女中生存人与死亡人数的比例图 二 可视化展示泰坦尼克号数据集中不同票价的人生存和死亡人数分布情况 三 可视化展示泰坦尼克号数据集中不同年龄的人生存与死亡人数分布情况 一 可视化展
  • Maven的基础知识

    Maven介绍 Maven 是一个项目管理和 综合工具 Maven 提供了开发人员构建一个完整的生命周期框架 开发团队可以自动完成项目的基础工具建设 Maven 使用标准的目录结构 和 默认构建生命周期 Maven是什么 它是一个 Apac
  • 各种绕过(MD5

    文章目录 MD5 0e开头的数组 MD5弱比较 MD5数组绕过 MD5 SQL注入 SHA1 SHA1弱比较 和 MD5弱类型比较同理 SHA1碰撞 MD5 0e开头的数组 MD5弱比较 QNKCDZO 240610708 byGcY so
  • 表设计为什么主键尽量无意义_奉上数据库表设计的十三条建议

    前言 本文总结了数据库表设计的十三条建议 这十三条建议只作为大家的参考 具体需要根据自己的项目来设计 来自 梦尘啊 链接 https juejin cn post 6902236691348586510 1 原始单据与实体之间的关系 表的设
  • Go:go mod vendor 使用

    Go go mod vendor 使用 1 背景 我们基于 go mod 机制来管理我们项目的依赖库版本 其中 go mod 记录了依赖库版本信息 一般第三方依赖库 包括公司内网gitlab上的依赖库 其源码都不被包含在我们的项目内部 而是
  • 5.自动装配:autowire=“byName“ or “byType“ + 使用注解【@Autowired 、@Qualifier、 @Resource】

    文章目录 自动装配说明 本博客环境搭建 自动装配 autowire byName 按名称自动装配 autowire byType 按类型自动装配 使用注解 1 Autowired 按类型自动转配的 不支持id匹配 2 Qualifier 不