首页 > 其他分享 >IOC/DI注解开发管理第三方bean

IOC/DI注解开发管理第三方bean

时间:2024-08-28 16:21:25浏览次数:11  
标签:DI 步骤 class ds bean 注解 IOC public

IOC/DI注解开发管理第三方bean

前面定义bean的时候都是在自己开发的类上面写个注解就完成了,但如果是第三方的类,这些类都是在jar包中,我们没有办法在类上面添加注解,这个时候该怎么办?

遇到上述问题,我们就需要有一种更加灵活的方式来定义bean,这种方式不能在原始代码上面书写注解,一样能定义bean,这就用到了一个全新的注解==@Bean==。

这个注解该如何使用呢?

文章目录

    • IOC/DI注解开发管理第三方bean
  • 一 环境准备
  • 二 注解开发管理第三方bean
        • 步骤1:导入对应的jar包
        • 步骤2:在配置类中添加一个方法
        • 步骤3:在方法上添加`@Bean`注解
        • 步骤4:从IOC容器中获取对象并打印
  • 三 引入外部配置类
    • 1 使用包扫描引入
          • 步骤1:在Spring的配置类上添加包扫描
          • 步骤2:在JdbcConfig上添加配置注解
          • 步骤3:运行程序
    • 2 使用`@Import`引入
          • 步骤1:去除JdbcConfig类上的注解
          • 步骤2:在Spring配置类中引入
          • 步骤3:运行程序
      • 知识点1:@Bean
      • 知识点2:@Import
  • 四 注解开发实现为第三方bean注入资源
    • 1 简单数据类型
      • 1.1 需求分析
      • 1.2 注入简单数据类型步骤
            • 步骤1:类中提供四个属性
            • 步骤2:使用`@Value`注解引入值
            • 扩展
    • 2 引用数据类型
      • 2.1 需求分析
      • 2.2 注入引用数据类型步骤
            • 步骤1:在SpringConfig中扫描BookDao
            • 步骤2:在JdbcConfig类的方法上添加参数
  • 五 总结

一 环境准备

学习@Bean注解之前先来准备环境:

  • 创建一个Maven项目

  • pom.xml添加Spring的依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>
    
  • 添加一个配置类SpringConfig

    @Configuration
    public class SpringConfig {
    }
    
  • 添加BookDao、BookDaoImpl类

    public interface BookDao {
        public void save();
    }
    @Repository
    public class BookDaoImpl implements BookDao {
        public void save() {
            System.out.println("book dao save ..." );
        }
    }
    
  • 创建运行类App

    public class App {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        }
    }
    

二 注解开发管理第三方bean

在上述环境中完成对Druid数据源的管理,具体的实现步骤为:

步骤1:导入对应的jar包
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>
步骤2:在配置类中添加一个方法

注意该方法的返回值就是要创建的Bean对象类型

@Configuration
public class SpringConfig {
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
步骤3:在方法上添加@Bean注解

@Bean注解的作用是将方法的返回值制作为Spring管理的一个bean对象

@Configuration
public class SpringConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

注意:不能使用DataSource ds = new DruidDataSource()

因为DataSource接口中没有对应的setter方法来设置属性。

步骤4:从IOC容器中获取对象并打印
public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        DataSource dataSource = ctx.getBean(DataSource.class);
        System.out.println(dataSource);
    }
}

至此使用@Bean来管理第三方bean的案例就已经完成。

如果有多个bean要被Spring管理,直接在配置类中多些几个方法,方法上添加@Bean注解即可。

三 引入外部配置类

如果把所有的第三方bean都配置到Spring的配置类SpringConfig中,虽然可以,但是不利于代码阅读和分类管理,所有我们就想能不能按照类别将这些bean配置到不同的配置类中?

对于数据源的bean,我们新建一个JdbcConfig配置类,并把数据源配置到该类下。

public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

现在的问题是,这个配置类如何能被Spring配置类加载到,并创建DataSource对象在IOC容器中?

针对这个问题,有两个解决方案:

1 使用包扫描引入

步骤1:在Spring的配置类上添加包扫描
@Configuration
@ComponentScan("com.leon.config")
public class SpringConfig {
	
}
步骤2:在JdbcConfig上添加配置注解

JdbcConfig类要放入到com.leon.config包下,需要被Spring的配置类扫描到即可

@Configuration
public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
步骤3:运行程序

依然能获取到bean对象并打印控制台。

这种方式虽然能够扫描到,但是不能很快的知晓都引入了哪些配置类,所有这种方式不推荐使用。

2 使用@Import引入

方案一实现起来有点小复杂,Spring早就想到了这一点,于是又给我们提供了第二种方案。

这种方案可以不用加@Configuration注解,但是必须在Spring配置类上使用@Import注解手动引入需要加载的配置类

步骤1:去除JdbcConfig类上的注解
public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
步骤2:在Spring配置类中引入
@Configuration
//@ComponentScan("com.leon.config")
@Import({JdbcConfig.class})
public class SpringConfig {
	
}

注意:

  • 扫描注解可以移除

  • @Import参数需要的是一个数组,可以引入多个配置类。

  • @Import注解在配置类中只能写一次,下面的方式是不允许的

    @Configuration
    //@ComponentScan("com.leon.config")
    @Import(JdbcConfig.class)
    @Import(Xxx.class)
    public class SpringConfig {
    	
    }
    
步骤3:运行程序

依然能获取到bean对象并打印控制台

知识点1:@Bean

名称@Bean
类型方法注解
位置方法定义上方
作用设置该方法的返回值作为spring管理的bean
属性value(默认):定义bean的id

知识点2:@Import

名称@Import
类型类注解
位置类定义上方
作用导入配置类
属性value(默认):定义导入的配置类类名,
当配置类有多个时使用数组格式一次性导入多个配置类

四 注解开发实现为第三方bean注入资源

在使用@Bean创建bean对象的时候,如果方法在创建的过程中需要其他资源该怎么办?

这些资源会有两大类,分别是简单数据类型引用数据类型

1 简单数据类型

1.1 需求分析

对于下面代码关于数据库的四要素不应该写死在代码中,应该是从properties配置文件中读取。如何来优化下面的代码?

public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

1.2 注入简单数据类型步骤

步骤1:类中提供四个属性
public class JdbcConfig {
    private String driver;
    private String url;
    private String userName;
    private String password;
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}
步骤2:使用@Value注解引入值
public class JdbcConfig {
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/spring_db")
    private String url;
    @Value("root")
    private String userName;
    @Value("password")
    private String password;
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}
扩展

现在的数据库连接四要素还是写在代码中,需要做的是将这些内容提

取到jdbc.properties配置文件,大家思考下该如何实现?

1.resources目录下添加jdbc.properties

2.配置文件中提供四个键值对分别是数据库的四要素

3.使用@PropertySource加载jdbc.properties配置文件

4.修改@Value注解属性的值,将其修改为${key},key就是键值对中的键的值

具体的实现就交由大家自行实现下。

2 引用数据类型

2.1 需求分析

假设在构建DataSource对象的时候,需要用到BookDao对象,该如何把BookDao对象注入进方法内让其使用呢?

public class JdbcConfig {
	@Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }
}

2.2 注入引用数据类型步骤

步骤1:在SpringConfig中扫描BookDao

扫描的目的是让Spring能管理到BookDao,也就是说要让IOC容器中有一个bookDao对象

@Configuration
@ComponentScan("com.leon.dao")
@Import({JdbcConfig.class})
public class SpringConfig {
}
步骤2:在JdbcConfig类的方法上添加参数
@Bean
public DataSource dataSource(BookDao bookDao){
    System.out.println(bookDao);
    DruidDataSource ds = new DruidDataSource();
    ds.setDriverClassName(driver);
    ds.setUrl(url);
    ds.setUsername(userName);
    ds.setPassword(password);
    return ds;
}

引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象。

五 总结

在这里插入图片描述

标签:DI,步骤,class,ds,bean,注解,IOC,public
From: https://blog.csdn.net/vV_Leon/article/details/141527558

相关文章

  • Redis几种常用数据类型的数据结构
    以下是redis-7版本以下适用stringint编码:当字符串长度小于等于12字节并且字符串可以表示为整数时,Redis会使用int编码。这样可以节省内存,并且在执行一些命令时可以直接进行数值计算。embstr编码:当字符串长度小于等于39字节时,Redis会使用embstr编码。这种编码方式会将......
  • [Paper Reading] Transfusion: Predict the Next Token and Diffuse Images with One
    Transfusion:PredicttheNextTokenandDiffuseImageswithOneMulti-ModalModellink时间:24.08机构:Waymo&UniversityofSouthernCaliforniaTL;DR提出一种使用混合模态token来训练transformer,名为transfusion,是一种生成式AI模型。主要工作使用了2T的tokens结合语言......
  • Redis组件介绍(一)
    写在前面今天我们来学习一下Redis。Redis是一个高性能的开源内存数据存储系统,支持多种数据结构,如字符串、列表、集合、有序集合和哈希表。#NoSQL概述随着大数据的兴起,数据量的暴增,数据类型的丰富,传统的关系数据库在应付动态网站,特别是超大规模和高并发的纯动态网站时已经......
  • 【阅己书城】docker部署MySQL及Redis
    一、MySQL1拉取mysql镜像dockerpullmysql:5.72启动mysql容器--name指定容器名字-v目录挂载-p指定端口映射-e设置mysql参数-d后台运行dockerrun--namemysql-v/mydata/mysql/data:/var/lib/mysql-v/mydata/mysql/conf:/etc/mysql-v/mydata/mysql/log:/var/......
  • Java后端微服务架构下的数据库分库分表:Sharding-Sphere
    Java后端微服务架构下的数据库分库分表:Sharding-Sphere大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!随着微服务架构的广泛应用,数据库层面的扩展性问题逐渐凸显。Sharding-Sphere作为一个分布式数据库中间件,提供了数据库分库分表的能力,帮助开发者解......
  • BeanUtils.copyProperties方法
    BeanUtils.copyProperties方法通常是通过反射(Reflection)实现的。这个方法是ApacheCommonsBeanUtils库中的一个核心功能,它允许开发者在运行时动态地访问和操作对象的属性和方法。通过使用反射,BeanUtils.copyProperties能够检查对象的类定义,找出可用的getter和setter......
  • [Paper Reading] One-Stage 3D Whole-Body Mesh Recovery with Component Aware Trans
    One-Stage3DWhole-BodyMeshRecoverywithComponentAwareTransformerlink时间:CVPR2023机构:粤港澳大湾区数字经济研究院(IDEA)&&清华大学深圳国际研究生院TL;DR使用一个纯Transformer结构模型(名为OSX)直接预测Body/Hand/Face的参数,避免了之前各模型分开预测后融合复......
  • Stable Audio文本转音乐 免费商用无版权限制 本地一键包使用教程
    StabilityAI的发布再次打破了创新的界限。这款前沿模型在其前作的成功基础上,增添了一系列突破性功能,可能彻底改变艺术家和音乐家创建及操作音频内容的方式。StableAudio2.0标志着人工智能生成音频的一个重要里程碑,为音质、多功能性和创意潜力设定了全新标准。这个模型......
  • Educational Codeforces Round 169 (Rated for Div. 2)
    A.ClosestPoint两个数时只要不相邻就有解,超过两个数无解点击查看代码#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineullunsignedlonglong#definepiipair<int,int>intread(){intx=0,f=0;charc=getchar();whi......
  • redis设置用户名密码
    今天学习redis的相关配置知识,起因来自于华为云服务器未设置用户名密码导致遭受到攻击,所以我要设置一个用户名密码,但是设置命令后出现这样的报错:Jobforredis.servicefailedbecausethecontrolprocessexitedwitherrorcode.See"systemctlstatusredis.service"and"j......