回顾

前几篇我们介绍各种依赖依赖注入,都是显式指定的,配置明确但同时也有些繁杂和重复。"很多发明的出发点,都是为了偷懒,懒人是推动社会进步的原动力"。Spring 提供了自动注入依赖的机制。

本文内容

  1. 什么是自动依赖注入,有什么优点

  2. autowire如何使用

  3. autowire-candidateprimary配合自动装配

什么是自动依赖注入,有什么优点

Spring 容器可以自动装配依赖 bean 之间的关系。 Spring 通过检查 ApplicationContext 容器中的内容自动解析依赖 bean (也就是其它 bean)。

优点如下:

  • 自动装配可以显著减少指定属性或构造函数参数的需要(偷懒使用)。
  • 自动装配可以随着对象的发展而更新配置。例如,如果需要向类添加依赖项,则无需修改配置即可自动满足该依赖项。因此,自动装配在开发过程中特别有用。

缺点如下:

  • propertyconstructor-arg设置中的显式依赖项总是会覆盖自动装配。不能自动装配简单的属性,如原语、字符串和类(以及此类简单属性的数组)。

  • 自动装配不如显式指定精确。

  • 对于可能生成文档的工具来说,装配信息可能不可用

  • 容器内的多个 bean 定义可能与要自动装配的 setter 方法或构造函数参数指定的类型匹配。如果是装配数组、集合、map这没有问题。但是,对于期望单个值的依赖项,这种歧义不会被任意解决,如果没有唯一的 bean 定义可用,则会引发异常。

autowire如何使用

当使用基于 XML 的配置元数据时,可以使用 <bean/> 元素的 autowire 属性为 bean 定义指定自动装配模式。共4种模式可以指定。

模式 说明
no (默认)不自动装配。 Bean 引用必须由 ref 元素定义。
byName 按属性名称自动装配。 Spring 寻找与需要自动装配的属性同名的 bean。
byType 根据类型自动装配。如果容器中恰好存在一个属性类型的 bean,则让属性自动装配;如果存在多个,则会抛出一个致命异常,表明不能为该 bean 使用 byType 自动装配;没有匹配的 bean,什么也没有发生(属性未设置)
constructor 类似于 byType 但适用于构造函数参数。如果容器中没有一个构造函数参数类型的 bean,则会引发致命错误。

使用 byTypeconstructor自动装配模式,可以装配数组和或是指定类型的集合。

来,直接上案例。

定义几个简单类

ServiceA依赖RepositoryARepositoryB

public class ServiceA {
private RepositoryA repositoryA;
private RepositoryB repositoryB;
// 忽略 Getter Setter
} public class RepositoryA implements RepositoryBase {
} public class RepositoryB implements RepositoryBase{
}

配置文件中指定自动装配

<bean class="com.crab.spring.ioc.demo05.ServiceA" id="serviceA" autowire="byType"/>

<bean class="com.crab.spring.ioc.demo05.RepositoryA"/>
<bean class="com.crab.spring.ioc.demo05.RepositoryB"/>

运行测试验证

@org.junit.Test
public void test() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("demo05/spring1.xml");
ServiceA serviceA = context.getBean(ServiceA.class);
RepositoryA repositoryA = context.getBean(RepositoryA.class);
RepositoryB repositoryB = context.getBean(RepositoryB.class);
System.out.println(serviceA);
System.out.println(serviceA.getRepositoryA() == repositoryA);
System.out.println(serviceA.getRepositoryB() == repositoryB);
context.close();
}

测试结果: ServiceA依赖RepositoryARepositoryB,容器自动装配成功

ServiceA{repositoryA=com.crab.spring.ioc.demo05.RepositoryA@150c158, repositoryB=com.crab.spring.ioc.demo05.RepositoryB@4524411f}

true

true

测试autowire="constructor"

定义测试类

public class ServiceB {
private RepositoryA repositoryA;
private RepositoryB repositoryB; public ServiceB(RepositoryA repositoryA, RepositoryB repositoryB) {
this.repositoryA = repositoryA;
this.repositoryB = repositoryB;
} @Override
public String toString() {
return "ServiceB{" +
"repositoryA=" + repositoryA +
", repositoryB=" + repositoryB +
'}';
}
}

配置文件

    <bean class="com.crab.spring.ioc.demo05.ServiceB" id="serviceA" autowire="constructor"/>

    <bean class="com.crab.spring.ioc.demo05.RepositoryA"/>
<bean class="com.crab.spring.ioc.demo05.RepositoryB"/>

测试方法及结果

@org.junit.Test
public void test_by_name() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("demo05/spring2.xml");
ServiceB serviceB = context.getBean(ServiceB.class);
System.out.println(serviceB);
context.close();
}
// 输出 符合预期
ServiceB{repositoryA=com.crab.spring.ioc.demo05.RepositoryA@3ecd23d9, repositoryB=com.crab.spring.ioc.demo05.RepositoryB@569cfc36}

autowire-candidateprimary配合自动装配

指定bean不参与自动装配

在每个 bean 的基础上,可以从自动装配中排除 bean。在 Spring 的 XML 格式中,将 <bean/> 元素的 autowire-candidate 属性设置为 false。注意:仅在按类型自动装配时生效。

<bean class="com.crab.spring.ioc.demo05.ServiceB" id="serviceA" autowire="constructor"/>

<bean class="com.crab.spring.ioc.demo05.RepositoryA" />
<bean class="com.crab.spring.ioc.demo05.RepositoryB"/>
<!--不参与自动装配-->
<bean class="com.crab.spring.ioc.demo05.RepositoryB" id="repositoryB2" autowire-candidate="false"/>

指定bean作为自动装配的主要候选人

<bean/> 标签上的元素primary可以指定bean作为自动装配时主要候选人

注意:仅在按类型自动装配生效。

  <!--主要候选人-->
<bean class="com.crab.spring.ioc.demo05.RepositoryB" id="repositoryB3" primary="true"/>

全局配置默认自动装配模式 default-autowire

<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"
default-autowire="byType"
>

全局限制自动装配候选者

顶级 <beans/> 元素在其 default-autowire-candidates 属性中接受一个或多个模式。例如,要将自动装配候选状态限制为名称以 Repository 结尾的任何 bean,请提供值 *Repository

<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"
default-autowire="byName"
default-autowire-candidates="Repository*"
>

总结

本文介绍和使用autowire来实现自动装配,分为全局和局部配置,局部优先。下一篇写bean的作用域。

本篇源码地址: https://github.com/kongxubihai/pdf-spring-series/tree/main/spring-series-ioc/src/main/java/com/crab/spring/ioc/demo05

知识分享,转载请注明出处。学无先后,达者为先!

Spring系列7:`autowire`自动装配怎么玩的更多相关文章

  1. Spring(五)--autowire自动装配和spel

    autowire自动装配和spel 1.需要的实体类 2.需要的配置文件 <?xml version="1.0" encoding="UTF-8"?> ...

  2. [原创]java WEB学习笔记99:Spring学习---Spring Bean配置:自动装配,配置bean之间的关系(继承/依赖),bean的作用域(singleton,prototype,web环境作用域),使用外部属性文件

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. Spring学习(六)-----Spring使用@Autowired注解自动装配

    Spring使用@Autowired注解自动装配 在上一篇 Spring学习(三)-----Spring自动装配Beans示例中,它会匹配当前Spring容器任何bean的属性自动装配.在大多数情况下 ...

  4. [转载]Spring Autowire自动装配介绍

    转自: http://www.cnblogs.com/zhishan/p/3190757.html 在应用中,我们常常使用<ref>标签为JavaBean注入它依赖的对象.但是对于一个大型 ...

  5. Spring Autowire自动装配介绍

    在应用中,我们常常使用<ref>标签为JavaBean注入它依赖的对象.但是对于一个大型的系统,这个操作将会耗费我们大量的资源,我们不得不花费大量的时间和精力用于创建和维护系统中的< ...

  6. Spring Autowire自动装配

    在应用中,我们常常使用<ref>标签为JavaBean注入它依赖的对象.但是对于一个大型的系统,这个操作将会耗费我们大量的资源,我们不得不花费大量的时间和精力用于创建和维护系统中的< ...

  7. spring bean autowire自动装配

    转自:http://blog.csdn.net/xiao_jun_0820/article/details/7233139 autowire="byName"会自动装配属性与Bea ...

  8. Spring autowire自动装配 ByType和ByName

    不使用自动装配前使用的是类的引用: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=& ...

  9. spring(4)——自动装配

    set注入和构造注入有时在做配置时比较麻烦.所以框架为了提高开发效率,提供自动装配功能,简化配置.spring框架式默认不支持自动装配的,要想使用自动装配需要修改spring配置文件中<bean ...

随机推荐

  1. 【LeetCode】934. Shortest Bridge 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS + BFS 相似题目 参考资料 日期 题目地 ...

  2. 【剑指Offer】丑数 解题报告

    [剑指Offer]丑数 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目描述: ...

  3. 1119 机器人走方格 V2

    1119 机器人走方格 V2 基准时间限制:1 秒 空间限制:131072 KB M * N的方格,一个机器人从左上走到右下,只能向右或向下走.有多少种不同的走法?由于方法数量可能很大,只需要输出Mo ...

  4. hdu-4561 连续最大积( 水题)

    http://acm.hdu.edu.cn/showproblem.php?pid=4561 求连续最大积. 他妈的狗逼思路到底咋说..... 思路是 %&*()*(&--))*)*& ...

  5. XSLT映射文件函数

    任何的编程语言或者是SQL语句都有内置的函数或方法,而强大灵活的xslt技术也是如此.熟练掌握XSLT的常用函数的用法,XSLT的应用将变得如此轻松,你会发现XSLT比想象中还要牛!以下是xslt数值 ...

  6. CS5265typec转HDMI2.0方案说明书|Capstone CS5265typec转HDMI4K60HZ单转电路|瑞奇达CS5265typec拓展坞设计

    一.CS5265总概 Capstone CS5265 USB Type-C到HDMI转换器结合了USB Type-C输入接口和数字高清多媒体接口(HDMI)输出.嵌入式微控制器(MCU)基于工业标准8 ...

  7. 使用.NET 6开发TodoList应用(15)——实现查询搜索

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 本文我们继续来看查询过程中的另外一个需求:搜索.搜索的含义是目标字段的全部或者部分值匹配请求中的搜索条件,对应到数据库层面是C ...

  8. Java面向对象笔记 • 【第6章 Java常用类】

    全部章节   >>>> 本章目录 6.1 Object类 6.1.1 Object类概述 6.1.2 Object的常用方法 6.1.3 实践练习 6.2 String类和St ...

  9. mongdb分片

    实验环境 主机              IP                虚拟通道 centos1       192.168.3.10         vmnet8 centos2       ...

  10. Pytest_参数化(10)

    pytest参数化有两种方式: mark的parametrize标记:@pytest.mark.parametrize(变量名,变量值),其中变量值类型为列表.元组或其它可迭代对象. fixture的 ...