【Spring面试全家桶】@Primary注解你真的会用吗

这篇具有很好参考价值的文章主要介绍了【Spring面试全家桶】@Primary注解你真的会用吗。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


@Primary注解是Spring Framework中的一个注解,用于标记具有多个实例的Bean的主要实例。以下是关于@Primary注解的知识点:
  1. @Primary注解的作用:@Primary注解用于标记具有相同类型的多个实例中的主要实例。当一个Bean需要注入这种类型的Bean时,Spring会注入使用@Primary注解标记的主要实例。
  2. @Primary注解的使用:在一个有多个实例的Bean中使用@Primary注解来标记主要实例。可以通过在Bean的类定义或构造函数参数中添加@Primary注解来使用它。
  3. @Primary注解的优先级:当一个类中有多个具有相同类型的Bean时,可以使用@Primary注解设置主要实例。主要实例优先于其他实例被注入。如果没有使用@Primary注解,则最后一个装配的Bean会被注入。
  4. @Primary注解的局限性:@Primary注解只适用于Bean的类型,不能用于Bean的名称。因此,如果有多个同一类型的Bean,但它们需要以不同的名称被注入,则无法使用@Primary来确定主要实例。
  5. @Qualifier和@Primary注解的区别:@Primary注解用于标记具有相同类型的多个实例中的主要实例。而@Qualifier注解用于标记具有特定名称的Bean,以便在多个具有相同类型的Bean中选择特定的实例。
    总之,@Primary注解是Spring Framework中的一个重要注解,用于标记具有多个实例的Bean的主要实例。它可以帮助解决多个同一类型的Bean被注入时的问题。

@Primary注解的作用

@Primary是一个Spring Framework的注解,用于标记一个bean(组件)是首选的bean(组件)。当多个相同类型的bean被定义时,被标记为@Primary的bean会被优先选择。该注解可以用于以下场景中:

  1. 当有多个同类型的bean时,注入第一个:例如,一个Spring应用程序中可能有多个名为“datasource”的DataSource实例,但应用程序可能需要使用其中一个特定的实例作为首选DataSource。可以通过在此标有@Primary注解的bean上使用@Autowired注解来指示Spring将此bean注入到所有需要Datasource依赖项的组件中。

  2. 当使用@Configuration注释的配置类时,作为默认bean:在使用@Configuration配置类时,可以将@Primary注解用于其中一个bean,以指示Spring在主配置类中定义的bean和其他@Configuration配置类中定义的bean之间选择该bean。

示例:

public interface PaymentService {
    void pay();
}

@Service
@Primary
public class AliPaymentServiceImpl implements PaymentService {
    @Override
    public void pay() {
        System.out.println("使用阿里支付");
    }
}

@Service
public class WxPaymentServiceImpl implements PaymentService {
    @Override
    public void pay() {
        System.out.println("使用微信支付");
    }
}

@Autowired
private PaymentService paymentService;

在这个例子中,我们定义了两个PaymentService的实现类,AliPaymentServiceImpl上应用了@Primary注解,表示它是优先选择的实现类。在使用@Autowired注入PaymentService的时候,Spring 会自动选择AliPaymentServiceImpl这个类。如果没有使用@Primary,会抛出NoUniqueBeanDefinitionException。

总之,@Primary注解是一个非常有用的注解,它可以让开发人员在多个同类型的bean中选择一个首选bean,避免了在使用注入时出现歧义的问题。

@Primary注解的使用

@Primary注解是Spring框架中的一个重要注解之一,用来标识一个bean是首选的(primary),在使用自动装配(auto-wiring)时,如果存在多个类型(type)相同的bean,Spring会优先选择标记为@Primary的bean进行注入。下面详细介绍@Primary注解的常见使用与高级用法。

1. 常见使用

@Primary注解常见使用场景如下:

1.1 在单个配置类中标记@Primary

在Spring配置类中,通过@Bean注解定义多个相同类型的bean时,可以使用@Primary注解标记一个首选的bean,例如:

@Configuration
public class AppConfig {

    @Bean
    public DataSource dataSource() {
        // ...
    }

    @Primary // 标记为首选bean
    @Bean("mySqlDataSource")
    public DataSource mySqlDataSource() {
        // ...
    }

    @Bean("oracleDataSource")
    public DataSource oracleDataSource() {
        // ...
    }
}

在上述配置中,如果需要注入DataSource,由于存在两个DataSource类型的bean,Spring会优先选择@Primary注解标记的mySqlDataSource。

1.2 在单个@Service、@Controller等注解的类中标记@Primary

在@Service、@Controller等注解的类中,如果存在多个相同类型的bean,也可以使用@Primary注解标记一个首选的bean,例如:

@Service
@Primary // 标记为首选bean
public class SomeServiceA implements SomeService {
    // ...
}

@Service
public class SomeServiceB implements SomeService {
    // ...
}

在上述配置中,如果需要注入SomeService,由于存在两个SomeService类型的bean,Spring会优先选择标记为@Primary的SomeServiceA。

2. 高级用法

除了常见使用场景,@Primary注解还有一些高级用法,如下:

2.1 使用@Qualifier与@Primary组合

@Qualifier注解是Spring提供的注解之一,用于指定一个特定的bean,例如:

@Component
public class SomeComponent {
    @Autowired
    @Qualifier("mySqlDataSource")
    private DataSource dataSource;
    // ...
}

在上述代码中,@Qualifier(“mySqlDataSource”)指定了需要注入的bean名称为mySqlDataSource的DataSource。然而,如果存在多个类型为DataSource的bean,这种方式可能会出现歧义,因此可以与@Primary注解组合使用,例如:

@Configuration
public class AppConfig {

    @Bean
    @Primary // 标记为首选bean
    @Qualifier("mySqlDataSource")
    public DataSource mySqlDataSource() {
        // ...
    }

    @Bean
    @Qualifier("oracleDataSource")
    public DataSource oracleDataSource() {
        // ...
    }
}

在上述配置中,指定@Qualifier(“mySqlDataSource”)时,由于存在两个DataSource类型的bean,但是标记为@Primary的mySqlDataSource会被优先选择。

2.2 使用@ConditionalOnMissingBean与@Primary组合

@ConditionalOnMissingBean注解是Spring提供的注解之一,用于判断当前上下文中是否存在指定类型(type)的bean,如果不存在,则创建一个新的bean。与@Primary注解结合使用时,可以在不存在指定类型的bean时创建标记为@Primary的bean,例如:

@Configuration
public class AppConfig {

    @Bean
    @Primary // 标记为首选bean
    @ConditionalOnMissingBean // 如果不存在 DataSource 类型的bean,则创建一个新的
    public DataSource dataSource() {
        // ...
    }
}

在上述配置中,如果当前上下文中不存在DataSource类型的bean,会创建标记为@Primary的dataSource,否则,已存在的bean会被优先选择。

3. 总结

@Primary注解是Spring框架中的一个重要注解,用来标识一个bean是首选的,在使用自动装配时,如果存在多个类型相同的bean,Spring会优先选择标记为@Primary的bean进行注入。除了常见使用场景外,@Primary注解还有一些高级用法,如与@Qualifier和@ConditionalOnMissingBean注解组合使用。在实际开发中,开发者可根据实际需求,选择合适的使用方式。

@Primary注解的优先级

@Primary注解是Spring框架提供的一个用于解决依赖注入歧义的注解。在一个类(或者一个接口)有多个实现类的情况下,@Primary注解可以指定其中一种实现类作为Spring容器中被注入的主要实现类。在使用@Autowired或者@Qualifier注入Bean时,如果没有指定具体的名称,那么Spring容器将会优先选择使用带有@Primary注解的Bean。

@Primary注解的优先级如下:

  1. @Primary注解具有最高优先级。如果一个类同时标注了@Primary注解和@Qualifier注解,那么@Primary注解会覆盖@Qualifier注解。

  2. @Primary注解作用于Bean的定义层(即在@Configuration或者@Component注解的类中定义的Bean),而不是作用于Bean的使用层。这意味着在使用@Autowired或者@Qualifier注解进行注入时,如果有多个同类型的Bean都标注了@Primary注解,那么Spring容器将会使用最先加载的那个@Primary注解的Bean进行注入。

  3. 如果在使用@Autowired或者@Qualifier注解时,没有特别指定Bean的名称或者类型,那么Spring容器会使用带有@Primary注解的Bean进行注入。

总的来说,@Primary注解可以非常方便地解决多个同类型Bean的注入问题,并且具有最高优先级,使用起来非常简单。但是需要注意的是,在使用@Primary注解时,一定要确保它标注的是正确的主要Bean,否则可能会引发一些意料之外的问题。

@Primary注解的局限性

@Primary注解是Spring框架中的一个非常常用的注解,主要用于在多个相同类型的bean中指定默认的实现。然而,@Primary注解也存在一些局限性,具体如下:

  1. 只能指定一个默认实现:@Primary注解只能用来指定一个默认实现,如果有多个实现,只能有一个默认实现。如果需要指定多个默认实现,则需要使用其他的方式,比如使用@Qualifier注解。

  2. 不可以与@Autowired注解同时使用:当我们使用@Primary注解指定默认实现时,如果需要在代码中注入bean实例,不可以使用@Autowired注解,因为这会导致Spring无法确定应该注入哪个bean实例。此时,我们需要使用@Qualifier注解来指定具体的bean实例。

  3. 无法应对特殊情况:虽然@Primary注解可以用来指定默认实现,但是在一些特殊情况下可能会失效,比如当我们在使用Spring的Profile功能时,如果针对不同的Profile配置了不同的bean实现,那么@Primary注解指定的默认实现可能会失效,此时我们需要使用其他方式来指定默认实现。

因此,虽然@Primary注解非常方便,但是在一些特殊情况下可能无法满足需求,需要使用其他方式来指定bean实现。

@Qualifier和@Primary注解的区别

在Spring框架中,@Qualifier和@Primary注解都是用来解决依赖注入中多个同类型Bean的问题,它们的功能略有不同。

@Qualifier注解是通过指定Bean的名称来指定注入哪个Bean,它可以和@Autowired或@Inject一起使用。如果存在多个同类型的Bean时,通过添加@Qualifier注解来指定需要注入的Bean,如下面的例子所示:

@Component
public class ClassA {
    ...
}

@Component
public class ClassB {
    ...
}

@Component
public class ClassC {
    
    @Autowired
    @Qualifier("ClassA")
    private ClassA classA;
    
    @Autowired
    @Qualifier("ClassB")
    private ClassB classB;
    
    ...
}

在上面的例子中,通过@Qualifier注解指定了需要注入的ClassA和ClassB。

@Primary注解是用来标记一个Bean为首选的Bean,当存在多个同类型的Bean时,会自动选择被@Primary标记的Bean注入,如下面的例子所示:

@Component
@Primary
public class ClassA {
    ...
}

@Component
public class ClassB {
    ...
}

@Component
public class ClassC {
    
    @Autowired
    private ClassA classA;
    
    @Autowired
    private ClassB classB;
    
    ...
}

在上面的例子中,ClassA被标记为@Primary,当注入ClassC中的classA时,会自动选择被标记为@Primary的ClassA注入。如果没有被标记为@Primary的Bean,则会报错。

总之,@Qualifier注解是用来指定具体的Bean名称来注入的;@Primary注解是用来标记一个首选的Bean,当存在多个同类型的Bean时,在没有指定具体注入哪个Bean时,会首先注入被标记为@Primary的Bean。

@Primary注解的底层工作原理

@Primary注解是Spring Framework中的一个注解,用于标记一个Bean作为默认Bean,在出现多个同类型的Bean时,优先使用被@Primary注解标记的Bean。

@Primary注解的底层工作原理可以分为以下几个步骤:

1.在BeanDefinition中注册Bean时,如果该Bean被@Primary注解标记,则会在BeanDefinition中添加一个primary属性,表示该Bean是默认Bean。

2.当Spring容器需要获取某个类型的Bean时,会先判断是否有该类型的@Primary注解标记的Bean,如果有,则直接使用该Bean。

3.如果没有@Primary注解标记的Bean,则会选择一个BeanDefinition中primary属性为true的Bean作为默认Bean。

4.如果BeanDefinition中没有primary属性为true的Bean,则会选择一个名称最小的Bean作为默认Bean。

总之,@Primary注解是通过标记BeanDefinition中的primary属性来实现的,而选择默认Bean则是通过选择具有primary属性的Bean或名称最小的Bean来实现的。在多个同类型的Bean中使用@Primary注解可以让我们更方便地控制默认Bean的选择,方便我们实现业务逻辑。

@Primary注解实战问题与解决方案

@Primary注解是Spring Framework提供的一种用于注入Bean的方式,它的作用是当有多个相同类型的Bean时,优先使用被@Primary注解的Bean。在实际开发中,经常会遇到使用@Primary注解的问题,下面介绍一些实战问题与解决方案。

问题一:多个同类型的Bean,如何确定哪个Bean被@Primary注解?

解决方案:在Spring容器启动时,会扫描所有被@Bean注解的方法,并将返回的对象作为Bean放入容器中。如果有多个同类型的Bean,需要在其中一个添加@Primary注解,表示优先使用该Bean。当需要使用该类型的Bean时,Spring Framework会自动选择@Primary注解的Bean。如果想要查看哪个Bean被@Primary注解,可以使用以下方法:

@Autowired
public void setBeans(List<TypeOfBean> beans) {
    for (TypeOfBean bean : beans) {
        if (bean.getClass().isAnnotationPresent(Primary.class)) {
            System.out.println(bean.getClass().getName() + " is @Primary");
        }
    }
}

该方法会自动查找所有类型为TypeOfBean的Bean,打印出被@Primary注解的Bean。

问题二:如何在不影响原有@Primary注解的前提下,指定使用其他Bean?

解决方案:在某些情况下,我们需要使用非@Primary注解的Bean,而不是默认的@Primary注解的Bean。可以使用@Qualifier注解指定使用哪个Bean。@Qualifier注解需要与@Autowired注解一起使用,如下所示:

@Autowired
@Qualifier("beanName")
private TypeOfBean bean;

其中,beanName为要使用Bean的名称。

问题三:如何在测试代码中使用不同的Bean?

解决方案:在测试代码中,与业务代码不同的是,我们可以使用不同的配置文件或者配置类进行测试,以达到使用不同的Bean的目的。可以通过在测试类中添加@ActiveProfiles注解,并指定使用的配置文件或配置类来实现。如下所示:

@SpringBootTest
@ActiveProfiles("test")
public class TestClass {
    ...
}

在这个例子中,我们可以在test配置文件中设置优先使用哪个Bean,或者在TestConfig配置类中设置优先使用哪个Bean。

以上是使用@Primary注解的一些实战问题与解决方案,希望能对您有所帮助。文章来源地址https://www.toymoban.com/news/detail-801069.html

到了这里,关于【Spring面试全家桶】@Primary注解你真的会用吗的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring boot kotlin webflux 或 web 多文件上传 报错400 415 No primary or single unique constructor found for

    #当我们使用Kotlin编写Spring Boot进行多文件上传的时候,传统的方法如下: 此时会有如下几种情况: 以上是第一种情况,直接报错,并提示无主构造函数。这时我们通过互联网搜索可能会在形参上加上: @RequestParam (web)或者 @RequestPart (webflux)。如下: 然后后端没报错了,返回值

    2024年02月15日
    浏览(40)
  • uniapp引入uview-ui 报错:$u-badge-primary: $u-primary !default;

    解决方法 上面这个问题是在引入 uview-ui 这个ui框架后出现的,那么具体的解决方法是在项目根目录下的 uni.scss 文件中引入uview对应的样式文件: 插件地址 uni-app 插件地址(可以搜索一些其他的可用插件): https://ext.dcloud.net.cn/ uView2.0重磅发布,利剑出鞘,一统江湖: https:

    2024年02月11日
    浏览(41)
  • 都听说过 lodash,但你会用吗?

    Lodash 是 JavaScript 社区最出名的一个工具库,提供了许多高效、高兼容性的工具函数。 不过,随着浏览器和 web 技术的发展,一些人开始反对在项目中使用 lodash。主要原因有: ES6 之后拓展了 JavaScript 特性,许多功能不再需要额外工具库。 现代浏览器对 ES 语法的支持性提升。

    2024年02月16日
    浏览(46)
  • 【C++_primary】类和对象 —— 类

    面向对象是一种更高级的编程方式 当谈论编程范式时,\\\" 面向过程 \\\" 和 “面向对象” 是两个重要的概念。 它们描述了编程的 不同方法和思维方式,以解决问题和构建应用程序 。下面让我们详细了解一下这两种编程范式。 面向过程编程 是一种以流程和步骤为中心的编程方式

    2024年02月10日
    浏览(35)
  • 快看!华为Python抢购脚本你会用吗?

    目录 1.前言 2.原理 3.下载Python 4.安装浏览器 5.安装浏览器驱动 6.安装依赖包 7.配置文件修改 8.运行main.py 9.特别说明 10.关注我 微信公众号:漫漫编程路 PS:公众号后台回复 “HW” 获取抢购软件!! 1.前言   鉴于最近不少小伙伴的后台的留言与提问,很多是关于该脚本如何使

    2024年01月22日
    浏览(49)
  • 【C++_primary】命名空间、输入输出流

    为了解决合作开发时的命名冲突问题,C++ 引入了命名空间(Namespace) 当我们编写代码时,可能会产生一些命名冲突,为了解决这一冲突引出了命名空间的概念 命名冲突的产生主要包括两个方面原因: 1、与库函数名冲突 2、工程中的冲突(比如多人共同完成一个项目时,写了

    2024年02月12日
    浏览(31)
  • C#12中的Primary Constructors(主构造函数)

    什么是主构造函数 把参数添加到class与record的类声明中就是主构造函数。例如 这种写法与以下代码写法一样 需要注意的是,类的所有其他构造函数都必须通过 this() 构造函数调用直接或间接调用主构造函数。 主构造函数参数的最常见用途包括但不限于以下几个方面: 初始化

    2024年02月05日
    浏览(38)
  • 【Spring全家桶系列】Spring中的事务管理(基于注解完成实现)

    ⭐️ 前面的话 ⭐️ 本文已经收录到《Spring框架全家桶系列》专栏,本文将介绍Spring中的事务管理,事务的概念与作用,以及Spring事务的属性和传播机制。 📒博客主页:未见花闻的博客主页 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 📌本文由 未见花闻 原创, CSDN 首发! 📆首

    2024年02月07日
    浏览(44)
  • Python中最常用的5种线程锁,你都会用吗

    对于日常开发者来讲很少会使用到本章节的内容,但是对框架作者等是必备知识,同时也是高频的面试常见问题。 线程安全是多线程或多进程编程中的一个概念,在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的

    2024年02月08日
    浏览(35)
  • selenium执行js代码的两个方法你都会用吗?

    在使用selenium做web自动化的时候,很多小伙伴反馈有些页面上动作我们无法通过selenium封装的方法直接去做,比如说修改元素的属性,影子节点的操作等等。需要使用原生的js代码去实现,而selenium也给我提供了两个执行js代码的方法,一个是execute_script,另一个是execute_async_s

    2024年04月28日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包