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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 通过@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;
}
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
9月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
641 26
|
11月前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
494 73
|
7月前
|
前端开发 IDE Java
Spring MVC 中因导入错误的 Model 类报错问题解析
在 Spring MVC 或 Spring Boot 开发中,若导入错误的 `Model` 类(如 `ch.qos.logback.core.model.Model`),会导致无法解析 `addAttribute` 方法的错误。正确类应为 `org.springframework.ui.Model`。此问题通常因 IDE 自动导入错误类引起。解决方法包括:删除错误导入、添加正确包路径、验证依赖及清理缓存。确保代码中正确使用 Spring 提供的 `Model` 接口以实现前后端数据传递。
250 0
|
11月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
296 12
|
11月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
399 12
|
11月前
|
Java Spring
【Spring配置相关】启动类为Current File,如何更改
问题场景:当我们切换类的界面的时候,重新启动的按钮是灰色的,不能使用,并且只有一个Current File 项目,下面介绍两种方法来解决这个问题。
228 10
|
11月前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
355 6
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
238 2
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
192 0
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
1017 1

热门文章

最新文章

下一篇
oss云网关配置