spring @Primary-在spring中的使用(转)
在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中的使用(转)的更多相关文章
- Spring Cloud Data Flow 中的 ETL
		
Spring Cloud Data Flow 中的 ETL 影宸风洛 程序猿DD 今天 来源:SpringForAll社区 1 概述 Spring Cloud Data Flow是一个用于构建实时数据 ...
 - 创建swagger的springboot-stater,并在spring cloud zuul网关中引入
		
Swagger 是一款RESTFUL接口的.基于YAML.JSON语言的文档在线自动生成.代码自动生成的工具. 通过在controller中添加注解,即可轻易实现代码文档化. Swagger提供ui界 ...
 - 【小家Spring】聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)
		
每篇一句 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 相关阅读 [小家Spring]聊聊Spring中的数据绑定 --- 属性访问器PropertyAccessor和 ...
 - 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 ...
 - Spring Batch在大型企业中的最佳实践
		
在大型企业中,由于业务复杂.数据量大.数据格式不同.数据交互格式繁杂,并非所有的操作都能通过交互界面进行处理.而有一些操作需要定期读取大批量的数据,然后进行一系列的后续处理.这样的过程就是" ...
 - Eclipse/JavaWeb (三)三大框架之Spring框架 持续更新中...
		
(一)发展历史 现在我们有三个层了,可是每层之间的调用是怎样的呢?比如显示层的struts需要调用一个业务类,就需要new一个业务类出来,然后使用:业务层需要调用持久层的类,也需要new一个持久层类出 ...
 - 从基础知识到重写Spring的Bean工厂中学习java的工厂模式
		
1.静态工厂模式其他对象不能直接通过new得到某个类,而是通过调用getInstance()方法得到该类的对象这样,就可以控制类的产生过程.顺带提一下单例模式和多例模式: 单例模式是指控制其他对象获 ...
 - Spring与Hibernate集成中的Session问题
		
主要讨论Spring与Hibernate集成中的session问题 1.通过getSession()方法获得session进行操作 public class Test extends Hibernat ...
 - spring mvc在Controller中获取ApplicationContext
		
spring mvc在Controller中获取ApplicationContext web.xml中进行正常的beans.xml和spring-mvc.xml的配置: 需要在beans.xml中进行 ...
 - J2EE进阶(五)Spring在web.xml中的配置
		
J2EE进阶(五)Spring在web.xml中的配置 前言 在实际项目中spring的配置文件applicationcontext.xml是通过spring提供的加载机制自动加载到容器中.在web ...
 
随机推荐
- [Agc029E]Wandering TKHS_树形dp_树上差分
			
Wandering TKHS 题目链接:https://atcoder.jp/contests/agc029/tasks/agc029_e 数据范围:略. 题解: 好神啊 Orz司队 https:// ...
 - PTA(Basci Level)1043.输出PATest
			
给定一个长度不超过 104 的.仅由英文字母构成的字符串.请将字符重新调整顺序,按 PATestPATest.... 这样的顺序输出,并忽略其它字符.当然,六种字符的个数不一定是一样多的,若某种字符已 ...
 - 并发一:Java内存模型和Volatile
			
并发一:Java内存模型和Volatile 一.Java内存模型(JMM) Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和在内存中取出变量的底层细节,是围绕着 ...
 - Exchanging Gifts--2019CCPC哈尔滨 E题
			
题意:http://codeforces.com/gym/102394/problem/E 1操作是给你一串数,2操作是连结两个串(所以可能很长),问你最后一个串的值(知道最多的个数就很好算,关键计算 ...
 - DEDE调用列表页,前台titlelen显示不全问题解决
			
一. 问题描述:{dede:list titlelen='100'}标题长度设为100后,但前台调用显示最长却只有60. 二. 产生原因:经过我多度查找,最终导致标题显示不全的原因是在DEDE生数据库 ...
 - 【Trie】Immediate Decodability
			
[题目链接]: https://loj.ac/problem/10052 [题意]: 就是给一些串,是否存在两个串是相同前缀的. [题解] 模板题,不想解释了. [代码]: #include<c ...
 - github骚操作
			
限制搜索 in关键词限制搜索范围 命令 说明 xxx in:name 项目名包含xxx的 xxx in:description 项目描述包含xxx的 xxx in:readme 项目的readme文件 ...
 - Django rest-framework框架-解析器
			
解析器: 开始: django: request.POST/ request.body 满足一下两个要求POST中才有值 1. 如果请求头中的 Content-Type: application/x- ...
 - PM2 部署 nodejs API项目
			
PM2的主要特性: 内建负载均衡(使用Node cluster 集群模块) 后台运行 0秒停机重载,我理解大概意思是维护升级的时候不需要停机. 具有Ubuntu和CentOS 的启动脚本 停止不稳定的 ...
 - js之数据类型(对象类型——单体内置对象——Math)
			
Math是一个内置对象,它具有数学常数和函数的属性和方法.Math对象用于执行数学任务,和其它对象不同,Math只是一个静态对象并没有Math()构造函数,实际上,Math()只是一个由js设置的对象 ...