回顾

前几篇我们介绍各种依赖依赖注入,都是显式指定的,配置明确但同时也有些繁杂和重复。"很多发明的出发点,都是为了偷懒,懒人是推动社会进步的原动力"。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】205. Isomorphic Strings 解题报告(Java & Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典保存位置 字典保存映射 日期 题目地址:http ...

  2. 【LeetCode】893. Groups of Special-Equivalent Strings 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  3. 【剑指Offer】复杂链表的复制 解题报告(Python)

    [剑指Offer]复杂链表的复制 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews 题 ...

  4. MySQL高级查询与编程笔记 • 【第1章 数据库设计原理与实战】

    全部章节   >>>> 本章目录 1.1 数据需求分析 1.1.1 数据需求分析的定义 1.1.2 数据需求分析的步骤和方法 1.1.3 数据流程图 1.1.4 数据字典 1. ...

  5. 使用tomcat搭建HTTP文件下载服务器

    使用tomcat搭建HTTP文件下载服务器, 有时我们的应用或者服务需要去外网下载一些资源, 但是如果在内网环境或者网络不好的情况下, 我们可以在内网提供文件下载服务, 将预先下载好的资源放在某个地方 ...

  6. websocket 使用 spring 的service层 ,进而调用里面的 dao层 来操作数据库 ,包括redis、mysql等通用

    1.前言 描述一下今天用websocket踩得坑  --->空指针异常! 我想在websocket里面使用service 层的接口,从中获取数据库的一些信息  , 使用 @Autowired 注 ...

  7. 虚拟机上CentOS7网络配置

    如果图片损坏:点击链接:https://www.toutiao.com/i6493449418249863693/ 设置网络 首先打开虚拟网络编辑器 权限打开 选择NAT模式,设置IP 应用确定之后, ...

  8. mybatis(CRUD)

    3.mybatis(CRUD) 有了mybatis,我们要对数据库进行增删改查只需要操作接口和mapper.xml文件,然后进行测试就可以了. 实例代码如下: 接口 public interface ...

  9. 构造注入链:POP

    1.POP链原理简介: 在反序列化中,我们能控制的数据就是对象中的属性值,所以在PHP反序列化中有一种 漏洞利用方法叫"面向属性编程",即POP( Property Oriente ...

  10. MySQL提权之mof提权

    mof提权原理 关于 mof 提权的原理其实很简单,就是利用了 c:/windows/system32/wbem/mof/ 目录下的 nullevt.mof 文件,每分钟都会在一个特定的时间去执行一次 ...