spring bean标签的primary属性用法讲解

目录
  • bean标签的primary属性
  • @Primary 在spring中常被忽视的注解
    • 下面是个简单的使用例子
    • 用@Qualifier这个注解来解决问题
    • 扩展:Spring注解常用汇总

bean标签的primary属性

primary这个翻译过来是 首要的,首选的意思。

primary的值有true和false两个可以选择。默认为false。

当一个bean的primary设置为true,然后容器中有多个与该bean相同类型的其他bean,

此时,当使用@Autowired想要注入一个这个类型的bean时,就不会因为容器中存在多个该类型的bean而出现异常。而是优先使用primary为true的bean。

不过,如果容器中不仅有多个该类型的bean,而且这些bean中有多个的primary的值设置为true,那么使用byType注入还是会出错。

@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") 存在多个实例配合使用

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring @Primary和@Qualifier注解原理解析

    一 前言 本篇内容主要是讲解2个重要的注解使用方式和场景,@Primary,@Qualifier注解:其作用就是消除bean注入时的歧义,能够让spring容器知道加载哪个bean: 知识追寻者(Inheriting the spirit of open source, Spreading technology knowledge;) 二 实现方式 如下示例中使用被单接口Sheet, 实现类为SheetA , SHeetB ; 由于注入容器时都是 Sheet类型,会发生异常,此时就是使用@Pri

  • 浅谈spring 常用注解

    我们不妨先将spring常用的注解按照功能进行分类 1 .将普通类加入容器形成Bean的注解 日常开发中主要使用到的定义Bean的注解包括(XML方式配置bean暂不讨论): @Component.@Repository.@Service.@Controller.@Bean 其中@Component.@Repository.@Service.@Controller实质上属于同一类注解,用法相同,功能相同,区别在于标识组件的类型.当一个组件代表数据访问层(Dao)时,你可以给它加上@Reposit

  • Spring常用注解汇总

    本文汇总了Spring的常用注解,以方便大家查询和使用,具体如下: 使用注解之前要开启自动扫描功能 其中base-package为需要扫描的包(含子包). <context:component-scan base-package="cn.test"/> @Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean. @Scope注解 作用域 @Lazy(true) 表示延迟初始化 @Service用于

  • spring bean标签的primary属性用法讲解

    目录 bean标签的primary属性 @Primary 在spring中常被忽视的注解 下面是个简单的使用例子 用@Qualifier这个注解来解决问题 扩展:Spring注解常用汇总 bean标签的primary属性 primary这个翻译过来是 首要的,首选的意思. primary的值有true和false两个可以选择.默认为false. 当一个bean的primary设置为true,然后容器中有多个与该bean相同类型的其他bean, 此时,当使用@Autowired想要注入一个这个类型

  • Spring Bean作用域与生命周期深入讲解

    目录 1.作用域定义 Bean 的作用域 Bean 的 6 种作用域 单例作用域(singleton)和全局作用域(application)区别 2.设置作用域 3.Bean 原理分析 3.1 Bean(Spring)执行流程 3.2 Bean生命周期 1.作用域定义 限定程序中变量的可用范围叫做作用域,或者说在源代码中定义变量的某个区域就叫做作用域. Bean 的作用域 而 Bean 的作用域是指 Bean 在 Spring 整个框架中的某种行为模式,比如 singleton 单例作用域,就表

  • Spring Bean的实例化之属性注入源码剖析过程

    前言 这一章节我们来讨论创建Bean过程中的属性注入,在Spring的IOC容器启动过程中,会把定义的Bean封装成BeanDefinition注册到一个ConcurrentHashMap中,Bean注册完成后,就会对单利的且lazy-init=false 的Bean进行实例化.创建Bean的代码在 AbstractAutowireCapableBeanFactory#doCreateBean 中,当Bean创建成功之后,会调用AbstractAutowireCapableBeanFactory

  • React state状态属性用法讲解

    目录 类组件中的state setState的用法 类组件如何限制state更新视图 setState原理揭秘 函数组件中的state useState的用法 如何监听state的变化 setState(dispatch)更新特点 useState的注意事项 总结 相同点 不同点 类组件中的state setState的用法 React项目中UI改变来源于state的改变,类组件中setState是更新组件,渲染视图的主要方式 基本用法 setState(obj,callback) 第一个参数:

  • spring bean标签中的init-method和destroy-method详解

    目录 1 背景介绍 2 init-method 3 destroy-method 4 总结 1 背景介绍 在很多项目中,经常在xml配置文件中看到init-method 或者 destroy-method .因此整理收集下,方便以后参考和学习.可以使用 init-method 和 destroy-method 在bean 配置文件属性用于在bean初始化和销毁某些动作时.这是用来替代 InitializingBean和DisposableBean接口. init-method 用于指定bean的

  • Spring Bean生命周期之属性赋值阶段详解

    目录 前言 属性自动装配 属性赋值前回调 属性的真正赋值 总结 前言 上节在谈论Bean的实例化过程时,在说明实例化后阶段时只是粗略地看了一下populateBean,并未展开分析.本节接着populateBean开始分析对象赋值阶段的事情. populateBean其实主要做了以下几件事: Bean实例化后回调,来决定是否进行属性赋值 (上节分析过了) 对属性进行自动装配 InstantiationAwareBeanPostProcessor属性赋值前回调 属性的真正赋值 protected

  • Spring入门到精通之Bean标签详解

    目录 Bean标签基本配置 Bean标签范围配置 Bean生命周期配置 Bean的依赖注入入门 Bean的依赖注入概念 Bean的依赖注入方式 Bean的依赖注入的数据类型 引入其他配置文件(分模块开发) Bean标签基本配置 用于配置对象交由Spring 来创建. 默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功. 基本属性: id:Bean实例在Spring容器中的唯一标识 class:Bean的全限定名称 Bean标签范围配置 scope:指对象的作用范围,取值如

  • Spring内部bean和级联属性用法详解

    1.内部bean 内部Bean和Java的匿名内部类相似,既没有名字,也不能被其他Bean引用,只能在声明处为外部Bean提供实例注入 配置文件 <bean id="boss2" class="com.gec.bean.Boss"> <property name="bossName"><value>马老板</value> </property> <property name=&qu

  • Spring Bean的属性注入方式

    在spring中bean的属性注入有两种 构造器注入 <bean id="car" class="nwtxxb.di.Car"> <constructor-arg index="0" type="java.lang.String" value="保时捷"></constructor-arg> <constructor-arg index="1"

  • Spring Bean属性注入的两种方式详解

    目录 属性注入概念 一.构造器注入 示例1 注意点 二.setter注入 示例2 三.如何选择注入方式 属性注入概念 Spring 属性注入(DI依赖注入)有两种方式:setter注入,构造器注入. 这个注入的属性可以是普通属性(基本数据类型与String等),也可以是一个引用数据类型(主要是对象),或者是一个集合(list.map.set等) 下表是属性注入bean标签中常用的元素 元素名称 描述 constructor-arg 构造器注入.该元素的 index 属性指定构造参数的索引(从 0

随机推荐