在spring 中使用注解,常使用@Autowired, 默认是根据类型Type来自动注入的。但有些特殊情况,对同一个接口,可能会有几种不同的实现类,而默认只会采取其中一种的情况下 @Primary 的作用就出来了。下面是个简单的使用例子。

有如下一个接口

public interface Singer {
String sing(String lyrics);
}

有下面的两个实现类:

@Component // 加注解,让spring识别
public class MetalSinger implements Singer{ @Override
public String sing(String lyrics) {
return "I am singing with DIO voice: "+lyrics;
}
}

//注意,这里没有注解

public class OperaSinger implements Singer {
@Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}

下面就是注入上面的

@Component
public class SingerService {
private static final Logger logger = LoggerFactory.getLogger(SingerService.class);
@Autowired
private Singer singer;
public String sing(){
return singer.sing("song lyrics");
}
}

I am singing with DIO voice: song lyrics. 原因很简单,就是 OperaSinger 这个类上面根本没有加上注解@Copmonent 或者 @Service, 所以spring 注入的时候,只能找到 MetalSinger 这个实现类. 所以才有这个结果。

但是如果一旦 OperaSinger 这个类加上了@Copmonent 或者 @Service 注解,有趣的事情就会发生,你会发现一个错误的结果或异常: 
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [main.service.Singer] is defined: expected single matching bean but found 2: metalSinger,operaSinger

提示很明确了,spring 根据类型无法选择到底注入哪一个。这个时候@Primay 可以闪亮登场了。

@Primary
@Component
public class OperaSinger implements Singer{ @Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}

如果代码改成这样,再次运行,结果如下: 
“I am singing in Bocelli voice: song lyrics”, 用@Primary 告诉spring 在犹豫的时候优先选择哪一个具体的实现。

二、用@Qualifier这个注解来解决问题

将上面的两个类改为如下:

@Component // 加注解,让spring识别
@Qualifier("metalSinger")
public class MetalSinger implements Singer{ @Override
public String sing(String lyrics) {
return "I am singing with DIO voice: "+lyrics;
}
} @Component
@Qualifier("opreaSinger")
public class OperaSinger implements Singer {
@Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}
@Component
public class SingerService {
private static final Logger logger = LoggerFactory.getLogger(SingerService.class); @Autowired
private Singer singer; @Qualifier("opreaSinger")
public String sing(){
return singer.sing("song lyrics");
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

扩展:Spring注解常用汇总

使用注解之前要开启自动扫描功能

其中base-package为需要扫描的包(含子包)

@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。 
@Scope注解 作用域 
@Lazy(true) 表示延迟初始化 
@Service用于标注业务层组件、 
@Controller用于标注控制层组件(如struts中的action) 
@Repository用于标注数据访问组件,即DAO组件。 
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 
@Scope用于指定scope作用域的(用在类上) 
@PostConstruct用于指定初始化方法(用在方法上) 
@PreDestory用于指定销毁方法(用在方法上) 
@Resource 默认按名称装配,当找不到与名称匹配的bean才会按类型装配。 
@DependsOn:定义Bean初始化及销毁时的顺序 
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常 
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用 
@Autowired @Qualifier(“personDaoBean”) 存在多个实例配合使用

原文链接:https://blog.csdn.net/qq_16055765/article/details/78833260

spring @Primary-在spring中的使用(转)的更多相关文章

  1. Spring Cloud Data Flow 中的 ETL

    Spring Cloud Data Flow 中的 ETL 影宸风洛 程序猿DD 今天 来源:SpringForAll社区 1 概述 Spring Cloud Data Flow是一个用于构建实时数据 ...

  2. 创建swagger的springboot-stater,并在spring cloud zuul网关中引入

    Swagger 是一款RESTFUL接口的.基于YAML.JSON语言的文档在线自动生成.代码自动生成的工具. 通过在controller中添加注解,即可轻易实现代码文档化. Swagger提供ui界 ...

  3. 【小家Spring】聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)

    每篇一句 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 相关阅读 [小家Spring]聊聊Spring中的数据绑定 --- 属性访问器PropertyAccessor和 ...

  4. 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

  5. Spring Batch在大型企业中的最佳实践

    在大型企业中,由于业务复杂.数据量大.数据格式不同.数据交互格式繁杂,并非所有的操作都能通过交互界面进行处理.而有一些操作需要定期读取大批量的数据,然后进行一系列的后续处理.这样的过程就是" ...

  6. Eclipse/JavaWeb (三)三大框架之Spring框架 持续更新中...

    (一)发展历史 现在我们有三个层了,可是每层之间的调用是怎样的呢?比如显示层的struts需要调用一个业务类,就需要new一个业务类出来,然后使用:业务层需要调用持久层的类,也需要new一个持久层类出 ...

  7. 从基础知识到重写Spring的Bean工厂中学习java的工厂模式

    1.静态工厂模式其他对象不能直接通过new得到某个类,而是通过调用getInstance()方法得到该类的对象这样,就可以控制类的产生过程.顺带提一下单例模式和多例模式:  单例模式是指控制其他对象获 ...

  8. Spring与Hibernate集成中的Session问题

    主要讨论Spring与Hibernate集成中的session问题 1.通过getSession()方法获得session进行操作 public class Test extends Hibernat ...

  9. spring mvc在Controller中获取ApplicationContext

    spring mvc在Controller中获取ApplicationContext web.xml中进行正常的beans.xml和spring-mvc.xml的配置: 需要在beans.xml中进行 ...

  10. J2EE进阶(五)Spring在web.xml中的配置

     J2EE进阶(五)Spring在web.xml中的配置 前言 在实际项目中spring的配置文件applicationcontext.xml是通过spring提供的加载机制自动加载到容器中.在web ...

随机推荐

  1. 《C++ Primer》读书笔记之第15章:面向对象编程

    一.面向对象概述 1. 面向对象的三个基本特性 封装.继承和多态. 2. 封装 指把隐藏对象的实现细节,仅对外提供接口,从而达到接口与实现分离的效果.封装的好处:一是提高数据的安全性,用户只能使用对象 ...

  2. Django使用DataTables插件总结

    Django使用Datatables插件总结 文章中的例子已上传至github 基本使用 Datatables插件是一款方便简单的展示数据的列表插件.关于基本使用,官方网站上的已介绍的很详细,这里我再 ...

  3. Spring实例化Bean三种方法:构造器、静态工厂、实例工厂

    Spring中Bean相当于java中的类,可以通过xml文件对bean进行配置和管理. 一.Bean的实例化: 构造器实例化.静态工厂实例化.实例工厂方式实例化. 目录: 构造器实例化: xml配置 ...

  4. c# dateTime格式转换为Unix时间戳工具类

    using System; using System.Collections.Generic; using System.Text; namespace TJCFinanceWriteOff.BizL ...

  5. VS code 的使用

    VS code 是一个非常不错的代码编辑器.它不依赖与任何编译器或者解释器,但却能高效的利用第三方编译器或解释器来给用户提供良好的代码编写环境. 我喜欢VS code的三点,丰富强大的插件,快捷的语法 ...

  6. C++编写DLL文件

    动态链接库DLL文件与EXE文件一样也是可执行文件,但是DLL也被称为库,因为里面封装了各种类.函数之类的东西,就像一个库一样,存着很多东西,主要是用来调用的.调用方式主要分为两种:隐式(通过lib文 ...

  7. windows下memcache扩展安装和搭建

    ### windows下memcache扩展安装和搭建 背景:在做微信公众号的开发时,token的有效期为7200秒,所以需要对token进行保存,在这选择了memcache作为缓存工具 memcac ...

  8. Sql Server 收缩日志文件原理及always on 下的实践

    一.准备知识 1.LSN LSN用来标识特定日志在日志文件中位置(详情请见什么是LSN:日志序列号),它由两部分组成:一部分用来标识VLF(虚拟日志文件)的序列号,剩下的用来标识该日志在VLF中的具体 ...

  9. hdu 2610 2611 dfs的判重技巧

    对于全排列枚举的数列的判重技巧 1:如果查找的是第一个元素 那么 从0开始到当前的位置看有没有出现过这个元素 出现过就pass 2: 如果查找的不是第一个元素 那么 从查找的子序列当前位置的前一个元素 ...

  10. python 比对PDF文件

    基本思路: 1.读取pdf内容,存放到不同的 list 2.比较 list 的相似度 ------------------------ 实现------------------------- 1.PD ...