Spring基础篇:通过@Component标注的类注入到其他Bean中

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 通过@Component标注的类注入到其他Bean中

例子

配置Dao操作接口,底层有通过MysqlOracle实现Dao的两种方式;

配置UserService接口和它的实现类UserServiceImpl,在实现类中通过类依赖注入的方式,将对应的底层实现注入,为了解耦的方便,配置注入的名称通过properties文件标注。

目录及代码说明

嫌啰嗦可以跳过这段:目录及代码说明

目录结构

image.png

Dao接口

public interface Dao {
    public String getUserNameById();
}

Dao的Mysql实现类代码

public class MysqlDaoImpl implements Dao {
    @Override
    public String getUserNameById() {
        return "mysql";
    }
}

Dao的Oracle实现类代码

public class OracleDaoImpl implements Dao {
    @Override
    public String getUserNameById() {
        return "oracle";
    }
}

UserService接口

public interface UserService {
    public String getUserNameByID();
}

UserService接口实现类代码

public class UserServiceImpl implements UserService {
    @Override
    public String getUserNameByID() {
        return null;
    }
}

步骤

第一步:需要将交给容器的类,用注解标注

  • MysqlDaoImplOracleDaoImpl两个类上面加上@Component注解
  • UserServiceImpl类上加上@Service注解
说明: @Service是基于 @Component的,它们的作用是一样的,只是作为架构方面来说,@Service能够提醒阅读代码的人,了解这是一个Service类。

第二步:配置配置类

@Configuration
@ComponentScan("juejin.autowrite")
public class AutoWriteConfig {
}

就是扫描配置注解的Bean

第三步:使用@Autowired注解

@Service
public class UserServiceImpl implements UserService {
    private Dao dao;

    @Autowired
    public void setDao(Dao dao) {
        this.dao = dao;
    }

    @Override
    public String getUserNameByID() {
        return dao.getUserNameById();
    }
}

我们的目的是:在ServiceImpl中需要用到Dao的实现,所以通过set方式上添加@Autowired注解,就可以自动将Spring容器中对应的类型注入到该属性中。

第三步:写启动类,启动

public class Application {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AutoWriteConfig.class);
        UserServiceImpl bean = ctx.getBean(UserServiceImpl.class);
        String name = bean.getUserNameByID();
        System.out.println(name);
    }
}

不出意外的话,你会得到一条报错信息NoUniqueBeanDefinitionException,这个错误在自动注入时经常出现呢。

原因:

  • Dao有两个实现类MysqlDaoImplOracleDaoImpl
  • 我们在Service中注入的是
    private Dao dao;

    @Autowired
    public void setDao(Dao dao) {
        this.dao = dao;
    }

注意,上面有提到过@Autowired是按照类型注入的,那么Dao现在有两个实现类,Spring容器已经无法分清到底需要哪个了。

解决 NoUniqueBeanDefinitionException 报错

1. 使用@Qualifier配合@Autowired

@Autowired
@Qualifier("mysqlDaoImpl")
public void setDao(Dao dao) {
    this.dao = dao;
}

输出:mysql

解释:这是因为@Qualifier告诉了Spring容器,我需要注入的Bean名称,Spring容器根据id找Bean就不会出现不知道找哪个的问题啦。

2. 使用@Primary注解

在Service中还是老样子

@Autowired
public void setDao(Dao dao) {
    this.dao = dao;
}

我们在Dao实现类OracleDaoImpl上加上@Primary注解

@Component
@Primary
public class OracleDaoImpl implements Dao {
    @Override
    public String getUserNameById() {
        return "oracle";
    }
}

输出:oracle

3.简化方法1,使用@Resource注解

@Resource = @Autowrite + @Qualifier
这个注解将两个注解合体使用啦,所以理解没有那么困难。

现状,硬编码的硬伤

@Autowired
@Qualifier("mysqlDaoImpl")
public void setDao(Dao dao) {
    this.dao = dao;
}

这个mysqlDaoImpl名字我是手动输入的,将它换成使用properties注入,更加灵活

创建properties文件

daoName=mysqlDaoImpl

在配置类中使用@PropertySource

用法见Spring基础篇:利用注解将外部Properties属性注入到Bean中的方法 - 掘金 (juejin.cn)

使用@Resource注解

配置name属性,通过配置的读取的外部文件,注入到name属性中,实现通过配置文件修改底部注入的类。

@Resource(name = "${daoName}")
public void setDao(Dao dao) {
    this.dao = dao;
}
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
128 73
|
7天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
7天前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
7天前
|
Java Spring
【Spring配置相关】启动类为Current File,如何更改
问题场景:当我们切换类的界面的时候,重新启动的按钮是灰色的,不能使用,并且只有一个Current File 项目,下面介绍两种方法来解决这个问题。
|
13天前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
50 6
|
15天前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
76 3
|
XML 前端开发 Java
Spring 最常用的 7 大类注解,史上最强整理!
随着技术的更新迭代,Java5.0开始支持注解。而作为java中的领军框架spring,自从更新了2.5版本之后也开始慢慢舍弃xml配置,更多使用注解来控制spring框架。
|
3月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
253 2
|
9天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
15天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
64 14