如何无侵入地引入第三方组件?

news2024/11/23 16:42:28

做java开发的小伙伴都知道,java的生态比较繁荣,有各种各样的第三方组件来满足我们日常的开发需求。很多常用的中间件(redis,kafka等)都提供java的开发接口,而且这些接口通常会被封装成比较好用的组件来满足我们使用这些中间件的场景需求。那么,你知道如何在把这些好用的第三方组件引入到我们的项目中吗?

通常java项目引入第三方组件的方式,主要是通过把第三方组件的jar包引入到当前项目中,而引入jar包通常使用一些依赖管理工具就可以了,如maven,gradel等。当jar引入到项目的类路径后,那么就可以直接使用里面的关键接口做开发了。

做java开发的老铁应该没有没用过spring的吧,如果有,那么接下来的内容可以跳过了(哈哈哈)。下面我们主要来学习一下,在spring框架下,如何优雅地将第三方组件中的接口,引入到我们的项目中。

为了方便下文描述,我们定义如下第三方组件:组件中只有一个类,用来实现将给定时间转换成“yyyy-MM-dd”格式的字符串(为了不增加读者理解负担,例子中组件实现的业务功能比较简单,但是足够说明问题)。

public class DateUtils {

    public String parse(Date date) {
        return new SimpleDateFormat("yyyy-mm-dd").format(date);
    }
}

组件的依赖管理采用maven管理:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>Utils</artifactId>
    <version>1.0-SNAPSHOT</version>

</project>

组件功能比较简单,自身没有依赖任何其他组件。

现在我们想在自己使用spring的项目中引入 DateUtils 这个类,实现日期格式转换。

一、将关键类作为Bean注入到IOC中

这种方式是最常用,也是最简单的方式,使用方法如下:

@Configuration
public class DateConfig {

    @Bean
    public DateUtils getDateUtils (){
        return new DateUtils();
    }
}

接下来,在项目需要DateUtils的地方,使用@Resource或者@Autowired等方式来完成DateUtils的依赖注入。

二、使用@Import

@Import注解的值是一个Class,使用方式如下:

@Import(xxx.class)

根据xxx的类型不同,Import解析xxx的方式也存在不同,在实际使用中,xxx同行有三种类型。
1、XXX是一个普通类,此时Import的作用就是将这个类加载到spring容器中


public class XXX {
	
	public String getName() {
		return "xxx";
	}
}

@Import(XXX.class)
public class ImportConfig {
	
}

2、xxx实现了ImportBeanDefinitionRegistrar接口,在重写的registerBeanDefinitions方法里面,能拿到BeanDefinitionRegistry,能手工往beanDefinitionMap中注册 beanDefinition。

public class XXX implements ImportBeanDefinitionRegistrar{
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		RootBeanDefinition bd = new RootBeanDefinition();
		bd.setBeanClass(YYY.class);
		registry.registerBeanDefinition("yyy", bd);
	}
} 

此时我们就把Person的BeanDefination放到了BeanDefinationMap中了,了解spring IOC的老铁都知道,bean其实就是通过BeanDefination中的class字段信息反射产生的,在使用YYY类的场景中,直接用@Autowired注入即可。

3、XXX实现了ImportSelector 重写selectImports方法该方法返回了String[]数组的对象,数组里面的类都会注入到spring容器当中,可以理解成第一种场景的增强版。


public class XXX implements ImportSelector {
 
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		return new String[] {YYYY.class.getName(),ZZZ.class.getName()};
	}

此时我们就把YYY和ZZZ都放到了spring的IOC容器了。

此时我们要把DateUtils引入到项目中,使用Import的任何一种方式都可以。

其实我们和可以在优化一下@Import的使用方式,让其更加优雅一些,我们在第三方组件中定义一个注解形如@EnableDateUtil,在该注解内使用@Import,这样我们的项目中只需要使用@EnableDateUtil注解即可,使用方式如下:
第三方组件:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(DateUtils.class)
public @interface EnableDateUtil {
}

需要注意此时第三方项目中要引入如下依赖,才能编译成功

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.3.12.RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.12.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

我们的项目:

@SpringBootApplication
@EnableDateUtil
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

这种方式在spring-cloud提供的一些组件中,使用的比较多,比如@EnableFeignClients。

三、自动转配

使用过springboot的老铁应该多少都了解过自动装配的原理,自动装配就是在项目启动过程中,springboot会读取类路径下META-INF目录下的spring.factories文件,并把其中 key为 "org.springframework.boot.autoconfigure.EnableAutoConfiguration"的部分类放到IOC容器中(只有"部分"类会放到IOC中,是因为会根据配置的Filter,对一些类进行过滤)。

基于自动装配的原理,我们的自定义的第三方组件也可以使用这种方式,把自己当做一个"Starter"提供给其他项目使用,具体方式如下:

第三方项目

在META-INF目录下添加文件 spring.factories文件
在这里插入图片描述

文件内容如下

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xxx.DateUtils

在我们的项目中,直接使用@Autowired或者@Resource把DateUtils注入进来,此种方式比第一种和第二种方式更加简单,无侵入,这也是springboot中starter的实现方式,怪不得我们在使用一些组件提供的Starter时,无需什么额外操作,就可以直接使用需要的接口了。

你还有其他在项目中引入第三方组件的方式吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/449504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot集成MyBatis-yml自动化配置原理详解

SpringBoot集成MyBatis-yml自动化配置原理详解 简介&#xff1a;spring boot整合mybatis开发web系统目前来说是市面上主流的框架&#xff0c;每个Java程序和springboot mybatis相处的时间可谓是比和自己女朋友相处的时间都多&#xff0c;但是springboot mybatis并没有得到你的真…

RabbitMQ--详情概述

一、消息队列(Rabbit Message Queue) 1、概念 消息队列是一种应用之间的通信方式&#xff0c;消息发送之后可以立即返回&#xff0c;由消息系统来确保消息的可靠传递。消息发布者只发布消息到MQ&#xff0c;消息使用者值从MQ中拿消息&#xff0c;两者不知道对方的存在。 简…

Sentinel——限流规则

目录 快速入门 簇点链路 案例 流控模式 流控模式——关联 流控模式——链路 案例 流控效果 流控效果——warm-up 流控效果——排队等待 热点参数限流 快速入门 簇点链路 簇点链路&#xff1a;就是项目内的调用链路&#xff0c;链路中被监控的每个接口就是一个资源。…

【故障检测】基于 KPCA 的故障检测【T2 和 Q 统计指数的可视化】(Matlab代码实现)

&#x1f4a5; &#x1f4a5; &#x1f49e; &#x1f49e; 欢迎来到本博客 ❤️ ❤️ &#x1f4a5; &#x1f4a5; &#x1f3c6; 博主优势&#xff1a; &#x1f31e; &#x1f31e; &#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 …

[前端基础]异步操作(还没写完)

1.写在前面 这篇是因为最近再写异步操作,需要点总结 因为还在学习前端的过程中嘛,所以有些东西可能会慢慢补充上来,也可能会有很多个人理解不是很到位的地方,还望各位评论区佬能帮忙指出.阿里嘎多捏 2.异步操作的概念和举例 异步操作和同步操作在408的三门课程中,都有所提及…

基于php的校园垃圾分类网站的设计与实现

摘要 近年来&#xff0c;随着民众环保意识的增强和资源有效利用问题的重视&#xff0c;全国各地市不断推进垃圾分类工作。教育部&#xff0c;也已于去年发布通知在全国各学校推进垃圾分类工作&#xff0c;以鼓励垃圾分类的有效实施。但现阶段我国校园的垃圾分类践行情况依旧问…

STATS 782 - Control Flow and Functions

文章目录 一、Control Flow1. If-Then-Else2. Loops 二、Functions1. Defining Functions2. 使用函数计算数学公式 总结 一、Control Flow 1. If-Then-Else > if (x > 0) y sqrt(x) else y -sqrt(-x)或 > y if (x > 0) sqrt(x) else -sqrt(-x)2. Loops ① fo…

数组应该怎么用?

文章目录 前言一、数组是什么&#xff1f;二、数组的创建1.数组的创建&#xff1a;2.数组的初始化 三.数组的遍历1.逐个打印2.使用for循环四.二维数组1.语法&#xff1a;2.遍历 五.数组的一些常用方法1.数组转换字符串2.数组拷贝3.二分查找4.冒泡排序5.数组逆序 总结 前言 为什…

动力节点Vue笔记——Vue与Ajax

四、Vue与AJAX 4.1 回顾发送AJAX异步请求的方式 发送AJAX异步请求的常见方式包括&#xff1a; 原生方式&#xff0c;使用浏览器内置的JS对象XMLHttpRequest const xhr new XMLHttpRequest()xhr.onreadystatechange function(){}xhr.open()xhr.send() 原生方式&#xff0…

_awt_container容器_演示

Component作为基类&#xff0c;提供了如下常用的方法来设置组件的大小、位置、可见性等。 方法签名方法功能setLocation(int x,int y)设置组件的位置setSize(int width,int heigth)设置组件的大小setBounds(int x,int y,int width,int heigth)设置组件的位置&#xff0c;大小。…

基于蚂蚁优化算法的BP神经网络在负荷预测中的应用研究(Matlab完整代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; 目录 1 ACO-BP算法 2 ACO-BP算法基本思路 3 具体步骤 4 运行结果 ​ 5 参考文献 6 Matlab代码实现 1 ACO-BP算法 传统的…

数组模拟实现单链表快速操作

前言&#xff1a;我们都知道链表的一般模式是由结构体加指针来实现的&#xff0c;但是在实际的比赛中&#xff0c;结构体指针来实现链表的操作并不常用&#xff0c;原因是因为我们在增加节点时需要开辟新的内存&#xff0c;而比赛时给出的样例大多都是十几万个数据&#xff0c;…

安装配置SVN版本控制管理工具

SVN工具能帮我们做什么&#xff1f; 核心功能&#xff1a;文档版本管理系统 适合对象&#xff1a;个人与团队都可以使用&#xff0c;企业中项目资源的重要管理工具 举例&#xff1a;一个文件夹里面的文档管理 1.下载安装SVN服务器 VisualSVN-Server 2.下载安装SVN客户端 T…

【论文阅读】CVPR2023 IGEV-Stereo

用于立体匹配的迭代几何编码代价体 【cvhub导读】【paper】【code_openi】 代码是启智社区的镜像仓库&#xff0c;不需要魔法&#xff0c;点击这里注册 &#x1f680;贡献 1️⃣现有主流方法 基于代价滤波的方法和基于迭代优化的方法&#xff1a; 基于代价滤波的方法可以在c…

大小字母转换

1.代码实例: public class UpString { public static void main(String[] args) { if(args!null && args.length 1){ String str new String(args[0]); System.out.println(“原字符&#xff1a;” str “\n”); String newA str.toUpperCase(); System.out.prin…

C语言分支和循环语句

目录 1.什么是语句&#x1f60a; 2.分支语句&#xff08;选择结构&#xff09;&#x1f60a; 2.1 if语句&#x1f43e; 2.2 switch语句&#x1f43e; 3.循环语句 &#x1f60a; 3.1 while循环&#x1f43e; 3.2 for循环&#x1f43e; 3.3 do...while()循环&#x1f43e…

太太太太太卷了,累了

我们聊到互联网行业的时候&#xff0c;一个不可避免的话题就是“内卷” 在程序员职场上&#xff0c;什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事&#xff0c;我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事&#xff0c;可遇不可求&#xff…

C++内联函数的使用

1.内联函数概念 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函数调用建立栈帧的开销&#xff0c;内联函数提升程序运行的效率。 如果在上述函数前增加inline关键字将其改成内联函数&#xff0c;在编译期间编译器会用…

[元来学NVMe协议] NVMe IO 指令集(NVM 指令集)| Flush 命令

声明 主页:元存储的博客_CSDN博客 依公开知识及经验整理,如有误请留言。 个人辛苦整理,付费内容,禁止转载。 内容摘要 前言 NVMe2.0 定义的三类命令集: 管理命令集、IO命令集、Fabrics命令集 Admin Command Set (管理命令集):用于控制器的管理,如创建/销毁IO提交队列…

春秋云境:CVE-2022-25401(任意文件读取漏洞)

目录 一、题目 二、curl访问flag文件 一、题目 介绍&#xff1a; Cuppa CMS v1.0 administrator/templates/default/html/windows/right.php文件存在任意文件读取漏洞 进入题目 是一个登录页面 sql和暴破都无解。 官方POC 国家信息安全漏洞库 cve漏洞介绍 官方给错了目录 …