文章目录

  • 概述
  • @Autowired注解
    • @Autowired的匹配原则
    • @Autowired的 required 属性
    • 使用@Primary 和@Qualifier消除@Autowired的歧义
      • @Primary 不推荐使用
      • @Qualifier推荐使用
  • 在构造函数/方法中使用@Autowired

概述

Spring Boot2.x-04Spring Boot基础-使用注解装配bean 中讲了如何将Bean装载到IoC容器中,这里我们说下Bean之间的依赖关系,当然了还是基于注解的方式。

xml的方式去描述Bean之间的依赖关系,请参考以前的博客

Spring-bean之间的关系

Spring-基于注解的配置[02自动装载bean]


@Autowired注解

举个例子: Manager可以安排Engineer去根据Engineer的类型做不同的工作

接口Engineer的接口方法是coding

package com.artisan.springbootmaster.di.intf;public interface Engineer {void coding();
}

假设有个Java程序猿,实现Engineer接口

package com.artisan.springbootmaster.di.intf.impl;import com.artisan.springbootmaster.di.intf.Engineer;
import org.springframework.stereotype.Service;@Service
public class JavaEnginerr implements Engineer {@Overridepublic void coding() {System.out.println("Java Engineer works");}
}

我们在实现类JavaEnginerr 上使用@Service注解,使其成为一个受Spring容器管理的bean。


接下来,我们来看下Manager类

package com.artisan.springbootmaster.di;import com.artisan.springbootmaster.di.intf.Engineer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class Manager {@AutowiredEngineer engineer;public void arrange(){engineer.coding();}}

可以通过arrange方法安排engineer工作。 这里Engineer 通过@Autowired让IoC容器自动注入进来。

接着我们使用Java类的方式来初始化IoC容器,通过@Configuration标注其是一个配置类 ,通过ComponetScan来扫描基包下面的标注了注解的类,使其成为受Spring IoC容器托管的bean,方便注入

package com.artisan.springbootmaster.di;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan(basePackages = "com.artisan.springbootmaster.*")
public class Config {}

最后,加载Java类的配置,主要是依靠 AnnotationConfigApplicationContext,启动容器获取bean,并调用对应的方法

package com.artisan.springbootmaster.di;import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class DITest {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);Manager manager =  applicationContext.getBean(Manager.class);manager.arrange();}
}

运行

23:04:08.018 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'manager'
Java Engineer works

@Autowired会根据属性的类型( by type )找到对应的 Bean 进行注入。

通过结果可以知道,通过注解@Autowired 成功的将JavaEngierr注入到了Manager实例中。


@Autowired的匹配原则

上面这个例子中@Autowired的用法很简单,我们继续来看下@Autowired

当然了,Engineer可能有多个,比如又来了个AndroidEngineer

package com.artisan.springbootmaster.di.intf.impl;import com.artisan.springbootmaster.di.intf.Engineer;
import org.springframework.stereotype.Service;@Service
public class AndroidEngineer implements Engineer {@Overridepublic void coding() {System.out.println("Android Engineer works");}
}

这是IDEA中可以看到,有提示报错了

让我们继续运行下DITest,抛出了异常

 No qualifying bean of type 'com.artisan.springbootmaster.di.intf.Engineer' available: expected single matching bean but found 2: androidEngineer,javaEnginerr

意思很明显,@Autowired根据类型来匹配Engineer,却发现有2个bean都是Engineer类型 ,这下子Spring不知道注入哪个了。

@Autowired的匹配原则:根据类型找到对应的 Bean,如果对应类型的 Bean 不是唯一 的,那么会继续根据其属性名称和 Bean 的名称进行匹配。如果匹配上,就会使用该 Bean,如果还无法匹配,就会抛出异常。

所以根据上面的原则,比较挫的一个办法(这里只是说可以这么改,但是肯定不推荐这么改

既然是两个,那我就让bean的名字一样呗

  • 方法一:Manager中的Engineer engineer保持不变,给这两个Engineer中的任意一个标注@Service(value "engineer"),指定其bean的名字为engineer,这样根据name就匹配上了,同样不会抛出异常。测试通过。
  • 方法二:Manager中的Engineer engineer改为这两个bean的任意一个名字,@Service标注的实现类Bean的名字为默认第一个字母小写其余保持不变,这样name也能匹配上,同样不会抛出异常。测试通过。

结果

这里只是举例验证下Spring @Autowired的匹配规则,实际工作中并不推荐这么改。。。。


@Autowired的 required 属性

@Autowired 是一个默认必须找到对应 Bean 的注解,如果不能确定其标注属性一定会存在并且允许这个被标注的属性为 null , 那么你可以配置@Autowired 属性 required 为 false.

@Autowired既可以标注在属性上,也可以标注在方法上

 @Autowired(required = false)

使用@Primary 和@Qualifier消除@Autowired的歧义

上面通过修改name,使其name保持一致的方式消除了歧义,可以正常的注入,不过并不推荐。

@Primary 不推荐使用

也可以使用@Primary,当然了,也不推荐这么干。 因为另外一个类也可以标注@Primary,Spring又无法知道注入哪个了。

注解@Primary是修改优先权的注解,像上面的两个例子,有2个beanandroidEngineer,javaEnginerr, 如果我们仅在JavaEnginerr这个类上标注@Primary,意思是告诉Spring IoC 容器 , 当发现有多个同样类型的 Bean ,请优先使用标注了@Primary的这个bean进行注入。

结果:


@Qualifier推荐使用

@Qualifier的value属性定义bean的名,该名称将会和@Autowired 组合在一起,通过类型和名称一起找到 Bean。Spring IoC容器中Bean 名称是唯一的标识,通过这个就可以消除歧义了

结果

即使 JavaEnginerr标注了@Primary,但是由于使用了@Qualifier,注入的依然是androidEngineer.


在构造函数/方法中使用@Autowired

上面的例子,我们是在属性上使用的@Autowired.
如果使构造函数呢?

我们改造下Manager

package com.artisan.springbootmaster.di;import com.artisan.springbootmaster.di.intf.Engineer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;@Component
public class Manager {Engineer engineer;public void arrange(){engineer.coding();}public Manager(@Autowired @Qualifier("javaEnginerr") Engineer engineer){this.engineer = engineer;}
}
  • 取消标注在属性上的注解
  • 在构造函数上增加注解,使用方法一样。
  • 如果仅有一个类型的Bean, @Qualifier就没有必要加上了。

运行

Spring Boot2.x-05Spring Boot基础-使用注解完成依赖注入相关推荐

  1. Wiring in Spring: @Autowired, @Resource and @Inject 三种注解实现依赖注入

    原文链接:Wiring in Spring: @Autowired, @Resource and @Inject 1. Overview 概述 In this Spring Framework tut ...

  2. Spring IoC和DI XML方式 注解方式 依赖注入 AOP面向切面

    初识Spring框架 时代变迁 原始时代我们用一个jsp搞定一切,但如此开发大型项目时我们遇到了问题,前端美化的代码和后端的代码交织,代码中又有html.js.css样式,又有业务逻辑和数据库访问代码 ...

  3. Spring使用注解配置依赖注入

    大部分情况下,使用Spring配置依赖注入时,都是使用注解来进行配置,因为注解比xml要方便和简单.不过类似于数据源对象这种配置信息容易变更的对象除外,这种对象使用xml文件来进行配置会更适合,方便于 ...

  4. 【IOC 控制反转】Android 事件依赖注入 ( 事件三要素 | 修饰注解的注解 | 事件依赖注入步骤 )

    文章目录 总结 一.Android 事件设置三要素 二.修饰注解的注解 三.Android 事件依赖注入步骤 总结 Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , ...

  5. Spring Boot2.x-04Spring Boot基础-使用注解装配bean

    文章目录 概述 通过Java配置文件@Bean的方式定义Bean 通过注解扫描的方式(@Component/@ComponentScan)装配Bean 使用excludeFilters属性不让IoC加 ...

  6. SSM框架—Spring基础—控制反转和依赖注入(概念)

    控制反转: 控制反转(IoC)是面向对象编程的一个设计原则,用于降低代码耦合度 在传统面向对象编程中,获取对象的方式是用关键字"new"主动创建一个对象,也就是说,应用程序掌握着对 ...

  7. spring的设计初衷,BOP 编程伊始,依赖注入的基本概念,AOP 编程理念

    Spring 的设计初衷 Spring 是为解决企业级应用开发的复杂性而设计,她可以做很多事.但归根到底支撑 Spring 的仅 仅是少许的基本理念,而所有的这些基本理念都能可以追溯到一个最根本的使命 ...

  8. Spring自学日志02(对象的创建,依赖注入)

    IOC创建对象的方式 无论是否使用,只有在xml文件中被注册(bean),就会被创建. 1.用无参构造创建对象 <!--无参构造创对象 类型 变量名 = new 类型(); Hello hell ...

  9. Spring中IoC两种接口和两种依赖注入方式的比较

    spring是一个开源框架,是为了解决企业应用程序开发的复杂性而创建的,为J2EE应用程序开发提供集成的框架.简单来说,spring是一个轻量级的控制反转IOC和面向切面AOP的容器框架.spring ...

最新文章

  1. Linux - 网络相关指令
  2. @Componet @Resource Spring
  3. sqlserⅴer随机函数_sql server 函数--rand() 生成整数的随机数
  4. 强化学习(五)---基于模型的强化学习实战
  5. 今天开通了博客园帐号
  6. 698. Partition to K Equal Sum Subsets
  7. Xcode 修改工程名以及注意事项
  8. 30 个 Python 的最佳实践、小贴士和技巧,不可错过哟!
  9. 如何在博客中插入数学公式
  10. mysql外部关联视图_MySQL数据库 : 自关联,视图,事物,索引
  11. Python+OpenCV:图像金字塔
  12. 数据挖掘实战—基于水色图像的水质评价
  13. 有关css3的一些问题
  14. 首次公开,整理12年积累的博客收藏夹,零距离展示《收藏夹吃灰》系列博客
  15. Mac野外动物高清动态桌面壁纸
  16. 面试官问你还有什么要问我的吗?
  17. Cabbage教学(5)——条件体
  18. Microsemi Libero使用技巧1——查看芯片资源占用情况
  19. javafx 教程_何时使用JavaFX代替HTML
  20. 马悦凌:从初级护士到“民间奇医”[1]

热门文章

  1. 女主计算机的学霸,又一部青春网剧开机,学霸女主牵手计算机大神,另类爱情精彩上演...
  2. “纯金”卫星,撞向我们的“蛋壳时代”
  3. 云服务器 小学生_日本小学生羡慕中国学生“钉”选之子,马云实现了他们的愿望...
  4. threadlocal内存泄露_ThreadLocal 简介
  5. mysql的单行注释_MySQL基础--会这些就够了
  6. 108. Leetcode 188. 买卖股票的最佳时机 IV (动态规划-股票交易)
  7. tensorflow 就该这么学--1
  8. torch_geometric 笔记:TORCH_GEOMETRIC.UTILS(更新中)
  9. R语言实战应用精讲50篇(十三)-如何使用JAVA调用R语言,两种语言的完美结合
  10. 纯干货-多场景下大屏可视化应用(文中含可视化源代码链接)