当前位置: 首页 > news >正文

简简单单探讨下starter

前言

     今天其实首先想跟大家探讨下:微服务架构,分业务线了,接入第三方服务、包啥的是否自己定义一个stater更好?


一、starter是什么?

在 Spring Boot 中,Starter 是一种特殊的依赖模块,用于快速引入一整套相关的依赖和默认配置,以简化开发者的配置工作。

1.starter的核心作用

Starter 的本质是一个 Maven 或 Gradle 的依赖包,它:

  • 封装了某种功能所需的所有依赖库;

  • 提供了该功能的默认自动配置;

  • 遵循 Spring Boot 的自动化配置规范(@Conditional 机制);

  • 允许用户覆盖默认配置。

2.Starter 的内部结构(自定义时)

一个典型的自定义 Starter 包含两个模块:

  • starter 模块:用于提供自动配置类(通常使用 @Configuration + @Conditional),并注入 Bean。

  • starter-autoconfigure 模块:用于定义配置逻辑和默认行为。

也有时候直接打包成一个模块就行。

二、Starter自定义步骤

首先了解下starter的目录结构:
在这里插入图片描述

1.目前idea的New没看到有直接选择Starter这种(有说new project,maven勾选Create from archetype,试了下跟新建module差不多),但是问题不大,可以直接New Module,具体:

  • 1.新建Module,设置好name、group、artifact等等,注意name最好是项目名称开头-spring-boot-starter-模块功能。比如我这里是接入虹软的人脸识别,所以名称:项目名称-spring-boot-starter-arcface
  • 修改pom
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><-- 这个父级依赖,如果没有需要的在父级其实可以不要 --><parent><groupId>com.bsr.healthcheck</groupId><artifactId>bsr-framework</artifactId><version>${revision}</version></parent><modelVersion>4.0.0</modelVersion><artifactId>bsr-spring-boot-starter-arcface</artifactId><packaging>jar</packaging><name>${project.artifactId}</name><description>虹软人脸扩展</description><url/><dependencies><!-- 自定义的通用包 --><dependency><groupId>com.bsr.healthcheck</groupId><artifactId>bsr-common</artifactId></dependency><!-- Spring 核心 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><optional>true</optional></dependency><!-- 虹软人脸识别 --><dependency><groupId>com.arcsoft.face</groupId><artifactId>arcsoft-sdk-face</artifactId><version>3.0.0.0</version><scope>system</scope><systemPath>${project.basedir}/libs/arcsoft-sdk-face-3.0.0.0.jar</systemPath></dependency></dependencies></project>
  • 因为虹软的jar,目前在maven源上没有公开,都是申请的时候下载的,这里在目录下建一个libs,放jar、dll(这个后期应该是放到服务器上)

  • 删除启动App、resources下的配置文件

  • resources下新建META_INF目录,目录下新建spring.factories,内容:org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.bsr.healthcheck.framework.face.config.ArcFaceAutoConfiguration
    注意ArcFaceAutoConfiguration配置类目录要跟计划写的类对得上哦,最好是检查写好了,这里能点过去就ok的

  • src下建目录,写配置类、properties等
    我的starter的目录:
    在这里插入图片描述

2.具体代码

ArcFaceAutoConfiguration

/*** 虹软人脸识别** @author zwmac*/
@Slf4j
@Configuration
@EnableConfigurationProperties(ArcFaceProperties.class)
@ConditionalOnProperty(prefix = "arcface", name = "enabled", havingValue = "true", matchIfMissing = true)
public class ArcFaceAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic FaceEngineWrapper faceEngineWrapper(ArcFaceProperties properties) {if (SystemUtil.getOsInfo().isWindows()){return new FaceEngineWrapper(properties.getWinAppId(),properties.getWinSdkKey(),properties.getWinLibPath());}if(SystemUtil.getOsInfo().isLinux()){return new FaceEngineWrapper(properties.getAppId(),properties.getSdkKey(),properties.getLibPath());}if(SystemUtil.getOsInfo().isMac()){log.info("虹软人脸识别不支持 Mac OS X");//throw new IllegalStateException("Unsupported OS for ArcFace engine");}log.warn("系统未知,虹软人脸识别引擎初始化失败");return null;}@Lazy@Bean@ConditionalOnMissingBeanpublic ArcFaceService arcFaceService() {return new ArcFaceServiceImpl();}}

FaceEngineConfig

/*** @author zwmac*/
@Configuration
public class FaceEngineConfig {@Value("${arcface.app-id}")private String appId;@Value("${arcface.sdk-key}")private String sdkKey;@Value("${arcface.lib-path}")private String libPath;@Beanpublic FaceEngineWrapper faceEngineWrapper() {return new FaceEngineWrapper(appId, sdkKey, libPath);}
}

FaceEngineWrapper


/*** @author zwmac*/
@Lazy
@Slf4j
public class FaceEngineWrapper {private FaceEngine faceEngine;/*** 初始化人脸引擎* @param appId 授权id* @param sdkKey 授权key* @param libPath 脚本路径*/public FaceEngineWrapper(String appId, String sdkKey, String libPath) {try {faceEngine = new FaceEngine(libPath);//激活引擎int errorCode = faceEngine.activeOnline(appId, sdkKey);if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {log.error("引擎激活失败");}ActiveFileInfo activeFileInfo = new ActiveFileInfo();errorCode = faceEngine.getActiveFileInfo(activeFileInfo);if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {log.error("获取激活文件信息失败");}//引擎配置EngineConfiguration engineConfiguration = new EngineConfiguration();engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);engineConfiguration.setDetectFaceMaxNum(10);engineConfiguration.setDetectFaceScaleVal(16);//功能配置FunctionConfiguration functionConfiguration = new FunctionConfiguration();functionConfiguration.setSupportAge(true);functionConfiguration.setSupportFace3dAngle(true);functionConfiguration.setSupportFaceDetect(true);functionConfiguration.setSupportFaceRecognition(true);functionConfiguration.setSupportGender(true);functionConfiguration.setSupportLiveness(true);functionConfiguration.setSupportIRLiveness(true);engineConfiguration.setFunctionConfiguration(functionConfiguration);//初始化引擎errorCode = faceEngine.init(engineConfiguration);if (errorCode != ErrorInfo.MOK.getValue()) {log.error("初始化引擎失败");}} catch (RuntimeException e) {log.error("人脸引擎FaceEngine加载脚本异常,{}", e.getMessage(), e);}}public FaceEngine getEngine() {return this.faceEngine;}
/*public void destroy() {faceEngine.unInit();}*/@PreDestroypublic void destroy() {if (faceEngine != null) {faceEngine.unInit();log.info("人脸识别引擎已释放");}}
}

ArcFaceProperties


/*** @author zwmac*/
@ConfigurationProperties(prefix = "arcface")
@Data
public class ArcFaceProperties {private String appId;private String sdkKey;private String libPath;private String winAppId;private String winSdkKey;private String winLibPath;private float matchThreshold = 0.8f;private float rgbThreshold;private float irThreshold;
}

ArcFaceService

/*** @author zwmac*/
public interface ArcFaceService {/*** 校验是否活体* @param imgFile 照片文件File* @return 是否活体*/boolean checkLive(File imgFile);
}

ArcFaceServiceImpl


/*** @author zwmac*/
@Slf4j
@Service
@RequiredArgsConstructor
public class ArcFaceServiceImpl implements ArcFaceService {@Resourceprivate FaceEngineWrapper engineWrapper;@Overridepublic boolean checkLive(File imgFile) {boolean liveOk = false;Assert.notNull(imgFile, "照片文件为空");ImageInfo imageInfo = getRGBData(imgFile);FaceEngine faceEngine = engineWrapper.getEngine();//人脸检测List<FaceInfo> faceInfoList = new ArrayList<>();int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);Assert.isTrue(errorCode == ErrorInfo.MOK.getValue(), "人脸检测失败");//特征提取FaceFeature faceFeature = new FaceFeature();errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature);Assert.isTrue(errorCode == ErrorInfo.MOK.getValue(), "人脸特征提取失败");//开启活体检测errorCode = faceEngine.setLivenessParam(0.5f, 0.7f);Assert.isTrue(errorCode == ErrorInfo.MOK.getValue(), "设置活体测试失败");List<LivenessInfo> livenessInfoList = new ArrayList<>();errorCode = faceEngine.getLiveness(livenessInfoList);Assert.isTrue(errorCode == ErrorInfo.MOK.getValue(), "活体检测失败");int liveness = livenessInfoList.get(0).getLiveness();log.info("活体liveness:{}", liveness);liveOk = liveness == 1;//释放引擎engineWrapper.destroy();return liveOk;}
}

总结

  • 这里的ArcFaceService在业务模块是可以懒加载的,好处就不解释了
  • 目前starter里service就写了一个接口,需要的可以自己扩展
  • 其实以前我也不赞成微服务还搞好多starter,但是最近想法有点改变。
    – 首先是业务线细分后,可能多个服务都需要接入某项技术,用starter可以细粒度管理模块。
    – 其次,让业务更加专注业务,第三方仅仅是第三方服务
    – 最后,其实就是可以复用,但是不得不说开发工作量增加了
  • 总结一句话:Spring Boot Starter 就是为了“开箱即用”而准备的功能集装箱。
    – 通过引入一个 starter,就可以获得一整套某个功能的支持,开发者只需关注业务逻辑,而无需自己配置和管理底层依赖。
         最后,希望能帮到大家,未来之所以迷人,是因为是机遇也是挑战,加油!

相关文章:

  • 手动移植UGUI
  • 网络原理1
  • Baklib内容中台AI重构智能服务
  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(31):そう
  • graphviz, dot, Error: lost rA sA edge; 独立的模块
  • CVE-2021-34429源码分析与漏洞复现
  • CCF CSP 第37次(2025.03)(3_模板展开_C++)(哈希表+stringstream)
  • Python数据可视化科技图表绘制系列教程(一)
  • 基于Python学习《Head First设计模式》第五章 单件模式
  • Docker部署与应用、指令
  • Qwen与Llama分词器核心差异解析
  • vue3学习
  • C++和C#界面开发方式的全面对比
  • 秋招Day12 - 计算机网络 - IP
  • 相机--相机成像原理和基础概念
  • 基于springboot的图书管理系统的设计与实现
  • Hadoop复习(九)
  • torch.distributed.launch 、 torchrun 和 torch.distributed.run 无法与 nohup 兼容
  • 如何制定数字化转型策略:从理念到落地的全面指南
  • 消费者行为变革下开源AI智能名片与链动2+1模式S2B2C商城小程序的协同创新路径
  • 做网站年赚千万/典型的网络营销案例
  • 自己怎么做视频收费网站/常见的系统优化软件
  • o2o商城上的二级网站/上海网站建设推广服务
  • 做网站公司排名电话/百度排行榜小说
  • 日主题wordpress/seo关键词
  • 做网站的得多少钱/微信朋友圈广告30元 1000次