【Spring】手写一个简易starter
需求:
自定义一个starter,里面包含一个@TimeLog注解和一个TimeLogAspect切面类,用于统计接口耗时。要求在其它项目引入starter依赖后,启动springboot项目时能进行自动装配。
步骤:
(1)引入pom依赖:
<dependencies><!-- starter想要有自动装配功能,就需要引入该依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId></dependency><!-- aop相关依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
(2)定义注解@TimeLog:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeLog {}
@Target:注解作用“对象”,这里声明注解作用在方法上。
@Retention:表示注解在运行时会被保留,可以通过反射机制读取。
(3)定义切面类TimeLogAspect:
@Aspect
@Component
public class TimeLogAspect {//切点:所有标注了TimeLog注解的方法@Pointcut("@annotation(com.hammajang.annotation.TimeLog)")public void timeConsume(){}@Around("timeConsume()")public Object doAround(ProceedingJoinPoint proceedingJoinPoint) {//开始时间long start = System.currentTimeMillis();Object result = null;try {//proceedingJoinPoint.proceed():真正的业务处理逻辑//result:业务的返回结果result = proceedingJoinPoint.proceed();} catch (Throwable e) {e.printStackTrace();}//结束时间long end = System.currentTimeMillis();System.out.println(proceedingJoinPoint.getSignature().getName() + "接口执行总耗时:" + (end - start) +"ms");return result;}
}
@Aspect:声明这是一个切面类。
@Component:声明这是一个bean,在项目启动时需要加载到Spring容器中。
(4)定义TimeLogProperties:
@ConfigurationProperties(prefix = "hammajang")
@Data
public class TimeLogProperties {/*** 日志开关*/private boolean enable;
}
@ConfigurationProperties:将配置文件中的属性绑定到 JavaBean(TimeLogProperties)中。注解声明了前缀是hammajang,获取以hammajang为前缀的所有参数进行自动匹配,赋值给类中对应的字段。
(5)定义TimeLogAutoConfiguration:
@Configuration
@ComponentScan(basePackages = "com.hammajang")
@ConditionalOnProperty(prefix = "hammajang",name = "enable",havingValue = "true")
@EnableConfigurationProperties(value = TimeLogProperties.class)
public class TimeLogAutoConfiguration {}
@Configuration:声明这是一个配置类(会被配置成bean,装载到spring容器中)。
@ComponentScan:扫描指定包路径(可以指定多个),将路径下符合要求的类对象配置成bean,装载到spring容器中。
@ConditionalOnproperty:表示配置文件中存在一个以"hammajang"为前缀的属性,属性名为"enable",当enable的值为true时(havingValue = "true"),才会将TimeLogAutoConfiguration配置类装载到spring容器中。
@EnableConfigurationProperties:启用指定配置类,value属性是一个class数组,表示可以启用多个配置类。
(6)编译、打包starter:
测试starter:
(1)在pom文件中引入我们自定义的starter:
<dependency><groupId>com.hammajang</groupId><artifactId>my-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version></dependency>
(2)在controller层编写测试接口:
@RestController
@RequestMapping("/order")
public class OrderController {@GetMapping("/test")@TimeLogpublic String test(){try {System.out.println("测试TimeLog注解...");//模拟业务处理Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}return "success";}
}
(3)测试@TimeLog注解是否生效:
测试结果:
相关文章:

【Spring】手写一个简易starter
需求: 自定义一个starter,里面包含一个TimeLog注解和一个TimeLogAspect切面类,用于统计接口耗时。要求在其它项目引入starter依赖后,启动springboot项目时能进行自动装配。 步骤: (1)引入pom依赖…...

Spring Cloud Alibaba实践 --Sentinel
sentinel介绍 Sentinel的官方标题是:分布式系统的流量防卫兵。从名字上来看,很容易就能猜到它是用来作服务稳定性保障的。对于服务稳定性保障组件,如果熟悉Spring Cloud的用户,第一反应应该就是Hystrix。但是比较可惜的是Netflix…...

使用Mockjs模拟(假数据)接口(axios)
一、什么是MockJs Mock.js官网 Mock.wiki.git mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。 二、安装mockjs npm install mockjs 三、 MockJs使用 简单使用: // 使用…...

【面试常考题目】五种方法解决“如何在n个无序数组中找出它的中位数(java)”问题
1.3 从N个数组中找到中位数,每一个数组可能乱序 在LeetCode上,"寻找多个数组的中位数"这类问题通常是由两个数组合并中位数问题(即LeetCode第4题)的变种或扩展。直接对应于多个数组合并后寻找中位数的题目在LeetCode上…...

打包CSS
接上一个打包HTML继续进行CSS的打包 1.在之前的文件夹里的src文件夹创建一个css文件 2.在浏览器打开webpack——>中文文档——>指南——>管理资源——>加载CSS 3.复制第一句代码到终端 4.复制下图代码到webpack.config.js脚本的plugins:[.....]内容下…...

Java项目开发,业务比较复杂如何减少bug
Java项目开发,业务比较复杂如何减少bug 当Java开发工作涉及复杂业务时,可以采取以下方法来减少bug的数量: 1、深入了解业务需求 充分了解业务需求,与业务人员进行充分的沟通和交流,确保对需求的理解正确。在需求分析…...

[EFI]Atermiter X99 Turbo D4 E5-2630v3电脑 Hackintosh 黑苹果efi引导文件
硬件型号驱动情况主板 Atermiter X99 Turbo D4 处理器 Intel Xeon E5-2630v3 已驱动内存Desktop DDR4 2666 MHz已驱动硬盘Netac NV7000已驱动显卡AMD Radeon RX 5700xt已驱动声卡瑞昱 英特尔 High Definition Audio 控制器ALC897已驱动网卡LucyRTL8125已驱动无线网卡蓝牙Broad…...

map.getOrDefault
map.getOrDefault 是 Java 中的一个方法,用于从 Map 中获取指定键的值,如果键不存在,则返回指定的默认值。 方法签名如下: V getOrDefault(Object key, V defaultValue) 其中,key 是要获取值的键,defaul…...

vue3移动端脚手架(纯净,集成丰富)
概述 一个纯净的移动端框架 ,用到了 Vue3 vuex Vite3 Vant3 sass eslint stylelint htmlhint husky commitlint axios axios-adapter VConsole 自定义全局 loading ,自定义函数式 dialog (api模仿微信小程序)&#x…...

HarmonyOS应用开发-手写板
这是一个基于HarmonyOS做的一个手写板应用,只需要简单的几十行代码,就可以实现如下手写功能以及清空画布功能。 一、先上效果图: 二、上代码 Entry Component struct Index {//手写路径State pathCommands: string ;build() {Column() {//…...

Python中的logging介绍
Python中的logging模块是一个强大的、灵活的、可配置的日志记录系统。它允许你在不修改源代码的情况下记录错误和调试信息,同时也可以对日志信息进行各种处理,例如写入到文件、输出到控制台、记录到数据库等。 logging模块提供了一种用于日志记录的通用接…...

ClickHouse(17)ClickHouse集成JDBC表引擎详细解析
JDBC 允许CH通过JDBC连接到外部数据库。 要实现JDBC连接,CH需要使用以后台进程运行的程序 clickhouse-jdbc-bridge。 该引擎支持Nullable数据类型。 建表 CREATE TABLE [IF NOT EXISTS] [db.]table_name (columns list... ) ENGINE JDBC(datasource_uri, exte…...

利用CRM系统分析客户行为:精细掌握市场动态
CRM客户关系管理软件在客户行为分析方面发挥着重要作用。通过CRM客户管理系统,企业可以更加便捷地统计客户的行为特征、消费习惯和消费需求,从而洞察市场趋势,帮助企业管理者精准制定营销策略。本文将通过购物篮分析的例子向您介绍CRM客户管理…...

15Linux、GIT及相关相似面试题、PostMan
Linux和git相似是命令相关的层次结构相似 Linux Linux Linux常用操作_linux操作-CSDN博客 程序员常用的10个Linux命令_简介linux系统中的10个常用命令及功能-CSDN博客 help help 命令 :获得 shell 内置命令的帮助信息,常用形式 help cd ls --help …...

游戏中小地图的制作__unity基础开发教程
小地图的制作 Icon标识制作制作摄像机映射创建地图UI效果“不一样的效果” 在游戏中经常可以看到地图视角的存在,那么地图视角是如何让实现的呢? 这一期教大家制作一个简易的小地图。 💖点关注,不迷路。 老样子,我们还…...

sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块
源代码: Lib/sqlite3/ SQLite 是一个C语言库,它可以提供一种轻量级的基于磁盘的数据库,这种数据库不需要独立的服务器进程,也允许需要使用一种非标准的 SQL 查询语言来访问它。一些应用程序可以使用 SQLite 作为内部数据存储。可…...

做数据分析为何要学统计学(0)——如果提高数据样本质量
样本是数据分析的关键,直接影响研究成果质量。如果样本质量不高,即使使用再好的分析方法,也无法得出理想的结论。所以数据学科圈里有句名言“数据比方法更重要”。所以如何提高数据样本的质量是保证研究成果质量的第一步,虽然这一…...

ubuntu18.04配置cuda+cudnn+tensorrt+anconda+pytorch-gpu+pycharm
一、显卡驱动安装 执行nvidia-smi查看安装情况 二、cuda安装 cuda官网下载cuda_11.6.2_510.47.03_linux.run,安装执行 sudo sh cuda_11.6.2_510.47.03_linux.run提升安装项,驱动不用安装,即第一项(Driver)ÿ…...

C++ 指针常量和常量指针的区别
指针常量 指针常量:顾名思义它就是一个常量,但是是指针修饰的。 格式为: int * const p //指针常量在这个例子下定义以下代码: int a,b; int * const p&a //指针常量 //那么分为一下两种操作 *p9;//操…...

如何截取Hive数组中的前N个元素?
文章目录 1、需求描述2、使用索引3、使用posexplode()4、转换为字符串操作 1、需求描述 需求:截取任意给定数组中的前N个元素,返回截取后的子数组 假设我们有如下三种类型的Hive数组: select array(1,2,3,4) -- [1,2,3,4] selec…...

iPaaS架构深入探讨
在数字化时代全面来临之际,企业正面临着前所未有的挑战与机遇。技术的迅猛发展与数字化转型正在彻底颠覆各行各业的格局,不断推动着企业迈向新的前程。然而,这一数字化时代亦衍生出一系列复杂而深奥的难题:各异系统之间数据孤岛、…...

UE4/UE5 修改/还原场景所有Actor的材质
使用蓝图方法: 1.修改场景所有Actor 材质: Wirframe:一个材质类 MatList:获取到的所有模型的全部材质 的列表 TempAllClass:场景中所有获取的 Actor 的列表 功能方法如下: 蓝图代码可复制在:…...

Three.js + Vue 处理glb文件过大问题(DRACOLoader加载压缩glb)
起因,three.js editer导出的glb文件过于庞大,导致部署后文件加载过久 解决方法: 第一步(得有个blender),压缩: 导出时把压缩勾选上 这时候我们会得到一个glb文件,但与three.js edite…...

ICC2:low power与pg strategy(pg_mesh)
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 用pg_strategy创建power stripe,示例如下: set pd_list {{DEFAULT_VA VDD_DIG VDD_DIG VSS} {PD_DSP VDD_DIG VDD_DSP VSS} } ;#两个电源域,DEFAULT_VA和PD_DSP是对应voltage area名字,其中D…...

Python基础期末复习 新手
类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响。 实例方法是一个普通的函数,类方法和静态方法都是通过函数装饰器的方式实现的;实例方法需要传入self,类方法需…...

建筑可视化数据大屏汇总,UI源文件(PC端大屏设计)
酷炫的大屏设计让数据更好的展现,方便业务人员分析数据,辅助领导决策。现在分享大屏Photoshop源文件,以下为部分截图示意。 划重点:文末可获得完整素材包~ 01 科技建筑平台数据可视化 02 建筑公司可视化数据汇总平台 03 深蓝…...

万户协同办公平台ezoffice wpsservlet接口任意文件上传漏洞
声明 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 一、漏洞描述 万户ezOFFICE协同管理平台是一个综合信息基础应用平台&am…...

shelve --- Python 对象持久化
源代码: Lib/shelve.py "Shelf" 是一种持久化的类似字典的对象。 与 "dbm" 数据库的区别在于 Shelf 中的值(不是键!)实际上可以为任意 Python 对象 --- 即 pickle 模块能够处理的任何东西。 这包括大部分类实例、递归数据…...

web服务器之——搭建两个基于不同端口访问的网站
要求如下: 建立一个使用web服务器默认端口的网站,设置DocumentRoot为/www/port/80,网页内容为:the port is 80。建立一个使用10000端口的网站,设置DocumentRoot为/www/port/10000,网页内容为:t…...

如何使用GaussDB创建外表(FOREIGN TABLE)
目录 一、前言 二、创建外表的特点 二、GaussDB创建外表访问外部数据库表(示例) 1、创建外表 2、FAQ:CREATE USER MAPPING错误 三、GaussDB创建外表映射数据文件(示例) 1、创建数据文件 2、创建外表 3、FAQ&a…...