AI智能
改变未来

Spring系列7:`autowire`自动装配怎么玩


回顾

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

本文内容

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

  2. autowire

    如何使用

  3. autowire-candidate

    primary

    配合自动装配

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

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

优点如下:

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

缺点如下:

  • property

    constructor-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,则会引发致命错误。

使用

byType

constructor

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

来,直接上案例。

定义几个简单类

ServiceA

依赖

RepositoryA

RepositoryB

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.Testpublic 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

依赖

RepositoryA

RepositoryB

,容器自动装配成功

ServiceAtruetrue

测试

autowire="constructor"

定义测试类

public class ServiceB {private RepositoryA repositoryA;private RepositoryB repositoryB;public ServiceB(RepositoryA repositoryA, RepositoryB repositoryB) {this.repositoryA = repositoryA;this.repositoryB = repositoryB;}@Overridepublic 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.Testpublic 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-candidate

primary

配合自动装配

指定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知识分享,转载请注明出处。学无先后,达者为先!

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » Spring系列7:`autowire`自动装配怎么玩