@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");
}
}
扩展:Spring注解常用汇总
使用注解之前要开启自动扫描功能
其中base-package为需要扫描的包(含子包)
<context:component-scan base-package="cn.test"/>
- @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") 存在多个实例配合使用
@Primary-在spring中常被忽视的注解的更多相关文章
- 在spring中常被忽视的注解 @Primary
在spring 中使用注解,常使用@Autowired, 默认是根据类型Type来自动注入的. 但有些特殊情况,对同一个接口,可能会有几种不同的实现类,而默认只会采取其中一种的情况下 @Primary ...
- Spring中的@Valid 和 @Validated注解你用对了吗
1.概述 本文我们将重点介绍Spring中 @Valid和@Validated注解的区别 . 验证用户输入是否正确是我们应用程序中的常见功能.Spring提供了@Valid和@Validated两个注 ...
- Spring 中的事务操作、注解、以及 XML 配置
事务 事务全称叫数据库事务,是数据库并发控制时的基本单位,它是一个操作集合,这些操作要么不执行,要么都执行,不可分割.例如我们的转账这个业务,就需要进行数据库事务的处理. 转账中至少会涉及到两条 SQ ...
- Spring中Bean管理的常用注解
在Spring中,主要用于管理bean的注解分为四大类:1.用于创建对象.2.用于给对象的属性注入值.3.用于改变作用的范围.4.用于定义生命周期.这几个在开发中经常接触到,也可以说每天都会遇见.其中 ...
- Spring中通过java的@Valid注解和@ControllerAdvice实现全局异常处理。
通过java原生的@Valid注解和spring的@ControllerAdvice和@ExceptionHandler实现全局异常处理的方法: controller中加入@Valid注解: @Req ...
- Spring中声明式事务的注解@Transactional的参数的总结(REQUIRED和REQUIRES_NEW的与主方法的回滚问题)
一.事务的传播行为1.介绍 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播.例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行.2.属性 事务的传播行为可以由传 ...
- Spring 中基于 AOP 的 @AspectJ注解实例
@AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格.通过在你的基于架构的 XML 配置文件中包含以下元素,@AspectJ 支持是可用的 ...
- spring中xml配置方式和注解annoation方式(包括@autowired和@resource)的区别
xml文件中配置itemSqlParameterSourceProvider是可以的: <bean id="billDbWriter" class="com.aa. ...
- 在使用spring中的ContextConfiguration、test注解时出现的错误
错误: 在使用测试注解时出现ContextConfiguration注解和test注解无法正常导包使用的编译异常,如图: 解决办法: 将pom.xml文件中以下依赖管理 中的<scope> ...
随机推荐
- (转)全局变量、extern/static/const区别与联系
全局变量.extern/static/const区别与联系 编译单元(模块): 在IDE开发工具大行其道的今天,对于编译的一些概念很多人已经不再清楚了,很多程序员最怕的就是处理连接错误(LIN ...
- 解析库之——beautifulsoup
阅读目录 一 介绍 二 基本使用 三 遍历文档树 四 搜索文档树 五 修改文档树 六 总结 一 介绍 Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通 ...
- HDU - 4609 3-idiots (FFT+母函数)
题意:给N个数,求任意选三个数能构成三角形的概率 分析:枚举两条边之和的复杂度\(O(N^2)\),显然不行,所以要更高效地做到枚举出两边之和. 所以用生成函数搭配FFT在\(O(NlogN)\)的时 ...
- Android开发环境配置到第一个程序所遇到的问题
1.安装顺序 先jdk,最后是1.7或1.8吧,配置环境变量:然后是sdk,配置环境变量:sdk安装之后即可以通过SDK Manager进行其他包的安装. 2.sdk及其他包的安装,以一张图表示,对于 ...
- pom.xml文件报错:web.xml is missing and <failOnMissingWebXml> is set to true
这个错误原因是因为项目无法加载到web.xml,所以需要配置web项目的目录.具体解决,配置步骤如下: 1.右键项目属性,配置项目目录 /src/main/webapp,如果没有,新增一条 2.配置 ...
- Linux学习笔记之阿里云ECS部署LAMP环境
LAMP指Linux+Apache+MySQL/MariaDB+Perl/PHP/Python,是一组常用来搭建动态网站或者服务器的开源软件.它们本身都是各自独立的程序,但是因为常被放在一起使用,拥有 ...
- HAL编译问题
1 make:进入目录'/opt/FriendlyARM/tiny4412/android/android-4.1.2'make: *** 没有规则可以创建“out/target/product/ge ...
- COGS 723. [SDOI2007] 超级数组
★★☆ 输入文件:arr.in 输出文件:arr.out 简单对比 时间限制:1 s 内存限制:3 MB Source: SDOI2007 Day2[问题描述] 一般的数组大家都经常 ...
- MySQL—记录的增删改查操作
1.插入记录: 方法一:INSERT [INTO] tbl_name [(col_name,···)] {VALUES|VALUE} ({expr |DEFAULT},···),(···),··· 例 ...
- C# Programming Guide-->Statements, Expressions, and Operators-->Anonymous Functions
C# Programming Guide Anonymous Functions Lambda Expressions Anonymous Methods In versions of C# befo ...