在带你玩转属于自己的spring-boot-starter系列(一)的时候与大家分享了如何编写自己的第一个starter,接着在带你玩转属于自己的spring-boot-starter系列(二)的时候与大家分享了如何加载默认属性到我们的starter中,那么在本章我们将结合第一章和第二章的内容我们写一个模拟的人脸识别的starter,我们的目标是,我们这个starter编写完成以后,开发人员直接引入我们的maven依赖就可以直接使用我们在上面的接口。
1、编写我们的人脸识别模块
1.1、创建人脸识别的核心工程
首先我们使用idea创建一个鉴权模块名称为“spring-starter-niu13-core”,以下为创建完成以后的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:///POM/4.0.0 https:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lazyboyl.niu13</groupId>
<artifactId>spring-starter-niu13-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-starter-niu13-core</name>
<description>一个牛叉的starter项目</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
工程目录如下所示:
1.2、创建核心模拟人脸识别的实现
接着我们在工程底下创建一个service的包,同时在该包底下创建一个模拟人脸识别的实现如下所示:
package com.lazyboyl.niu13.core.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @author linzf
* @since 2020/9/21
* 类描述:
*/
@Service
public class Niu13Service {
private Logger log = LoggerFactory.getLogger(Niu13Service.class);
@Value("${xxxface.url}")
private String url;
@Value("${xxxface.key}")
private String key;
public boolean faceCheck() {
log.info("你正在使用{}通过{}来获取人脸识别的结果", key, url);
return true;
}
}
1.3、创建核心模拟人脸识别的接口调用的实现
接着我们在工程底下创建一个controller的包,同时在该包底下创建一个模拟人脸识别接口调用的实现如下所示:
package com.lazyboyl.niu13.core.controller;
import com.lazyboyl.niu13.core.service.Niu13Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author linzf
* @since 2020/9/22
* 类描述:
*/
@RestController
public class Niu13Controller {
@Autowired
private Niu13Service niu13Service;
@GetMapping("faceCheck")
public String faceCheck(){
niu13Service.faceCheck();
return "人脸识别接口调用";
}
}
1.4、创建属性的枚举类
接着我们在constant包底下创建配置的枚举类,代码如下所示:
package com.lazyboyl.niu13.core.constant;
/**
* @author linzef
* 类描述: 配置属性的枚举类
*/
public enum FaceConstant {
URL("xxxface.url","http:///get"),
KEY("xxxface.key","abcdefghijklmn");
private String key;
private String defaultValue;
FaceConstant(String key, String defaultValue) {
this.key = key;
this.defaultValue = defaultValue;
}
public String getKey() {
return key;
}
public String getDefaultValue() {
return defaultValue;
}
}
1.5、实现spring的扫描注入
首先我们需要定义一个bean的扫描器的实现,这个我们只需要继承“ClassPathBeanDefinitionScanner”即可,代码如下所示:
package com.lazyboyl.niu13.core.config;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.env.Environment;
import java.util.Arrays;
import java.util.Set;
/**
* @author linzf
* @since 2019/7/22
* 类描述:实现拦截器的自定义的扫描
*/
public class ClassPathNiu13SecurityScanner extends ClassPathBeanDefinitionScanner {
public ClassPathNiu13SecurityScanner(BeanDefinitionRegistry registry) {
super(registry);
}
public ClassPathNiu13SecurityScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
super(registry, useDefaultFilters);
}
public ClassPathNiu13SecurityScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {
super(registry, useDefaultFilters, environment);
}
/**
* 功能描述: 实现spring的的扫描注入
* @param basePackages
* @return
*/
@Override
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
if (beanDefinitions.isEmpty()) {
logger.warn("No DgbSecurity Spring Componet was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
}
return beanDefinitions;
}
}
接着实现我们的类以及属性的扫描注入逻辑,代码如下:
package com.lazyboyl.niu13.core.config;
import com.lazyboyl.niu13.core.constant.FaceConstant;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.type.AnnotationMetadata;
import java.util.Properties;
/**
* @author linzf
* @since 2020/9/21
* 类描述: 将默认的注解注入spring体系的
*/
public class FaceScannerRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
ClassPathNiu13SecurityScanner scanner = new ClassPathNiu13SecurityScanner(registry);
ConfigurableEnvironment c = (ConfigurableEnvironment) environment;
MutablePropertySources m = c.getPropertySources();
Properties p = new Properties();
for (FaceConstant fc : FaceConstant.values()) {
String val = environment.getProperty(fc.getKey());
if (val == null || "".equals(val)) {
p.put(fc.getKey(), fc.getDefaultValue());
}
}
m.addFirst(new PropertiesPropertySource("defaultProperties", p));
scanner.doScan("com.lazyboyl.niu13.core");
}
}
1.6、创建我们的starter的配置文件
代码如下所示:
package com.lazyboyl.niu13.core.autoconfigure;
import com.lazyboyl.niu13.core.config.FaceScannerRegister;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* @author linzf
* @since 2020/9/21
* 类描述:
*/
@Configuration
@Import({FaceScannerRegister.class})
@ConditionalOnProperty(
prefix = "xxxface",
name = "isopen",
havingValue = "true"
)
public class StarterAutoConfigure {
}
1.7、配置我们的starter
最后在我们的resource文件夹底下创建一个META-INF文件夹,然后再这个文件夹底下创建一个spring.factories文件,该文件的内容如下所示:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lazyboyl.niu13.core.autoconfigure.StarterAutoConfigure
接着我们新增一个spring-configuration-metadata.json配置文件,主要用于在我们使用IDEA开发的时候当我们输入xxxface的时候回给出相应的提示,代码如下所示:
{
"properties": [
{
"name": "xxxface.url",
"type": "java.lang.String",
"description": "脸部识别的地址",
"defaultValue": "http:///get"
},
{
"name": "xxxface.key",
"type": "java.lang.String",
"description": "脸部识别的key",
"defaultValue": "abcdefghijklmn"
},
{
"name": "xxxface.isopen",
"type": "java.lang.Boolean",
"description": "脸部识别是否打开的标志",
"defaultValue": false
}
]
}
2、验证我们的人脸识别模块
2.1、创建application不做任何配置的时候是否可以正常调用我们的人脸识别的接口
首先我们使用idea创建一个鉴权模块名称为“spring-starter-niu13-demo-one”,这边一定要记得引入前面我们编写好的核心工程的maven依赖,以下为创建完成以后的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:///POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:///POM/4.0.0 https:///xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lazyboyl.niu13</groupId>
<artifactId>spring-starter-niu13-demo-one</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-starter-niu13-demo-one</name>
<description>验证niu13核心包</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.lazyboyl.niu13</groupId>
<artifactId>spring-starter-niu13-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.2、验证效果
我们直接启动当前的“spring-starter-niu13-demo-one”这个工程,接着我们浏览器地址栏输入http:\127.0.0.1:8080/faceCheck,这时候大家可以在浏览器看到如下的页面:
没错就是404的页面,这就是我们想要的效果,因为我们在配置中已经声明了我们必须要在配置文件中将“xxxface.isopen”的值设置为true,spring才会按着我们的规则注入我们的人脸识别的模块,因此我们在当前验证工程的application.properties配置文件中增加以下的配置:
xxxface.isopen=true
接着我们再次启动我们的工程,这时候大家再访问http:\127.0.0.1:8080/faceCheck,这时我们就可以看到可以正常访问了,且后台还会打印以下的信息。
到此为止我们就验证了我们的设想了,那么你这时候可以试着将你自己编写的牛叉的某块用starter包装发布到maven中央仓库给大家愉快的玩耍了。