手把手教你手写一个最简单的 Spring Boot Starter

Starter 命名规则


Spring 官方定义的 Starter 通常命名遵循的格式为 spring-boot-starter-{name},例如 spring-boot-starter-data-mongodb。Spring 官方建议,非官方 Starter 命名应遵循 {name}-spring-boot-starter 的格式,例如,myjson-spring-boot-starter。

自定义一个 Starter


了解了 Starter 的含义以及应用场景后,我们可以尝试手写一个 Starter,加深对它的了解以及能在实际工作中,开发出自己的 Starter,提高我们的开发效率。

可能有人会问 Starter 能干嘛呢?其实在我们的日常开发工作中,总有一些独立于业务系统之外的配置模块,它是可以在不同项目中进行复用的。如果在每个项目中都编写重复的模块代码,不仅浪费时间和人力,而且还和项目耦合。所以我们将这些可独立于业务代码之外的功能配置模块封装成一个 Starter,在需要用到此功能模块的项目中,只需要在其 pom.xml 文件中引用依赖即可,SpringBoot 帮我们完成自动装配,而且我们还可以在配置文件中调整 Starter 中默认的配置信息。

假设我们现在需要实现这样一个功能:

  1. 根据用户提供的 Java 对象,将其转换为 JSON 形式,并且在 JSON 字符串中添加指定的前辍和后辍。

  2. 用户可以动态改变前辍和后辍,即可在 yml 或 properties 配置文件中自定义。

举个栗子,假如用户输入下面这个类的对象 person:

public class Person {

private String name;

private int age;

private String address;

public Person(String name, int age, String address) {

super();

this.name = name;

this.age = age;

this.address = address;

}

// 省略get和set方法

}

Person person = new Person(“Mr.nobody”, 18, “拉斯维加斯”);

并假设用户在 application.yml 配置文件中配置的前辍为 @,后辍为 %,则最终生成的字符串为:

@{“address”:“拉斯维加斯”,“age”:18,“name”:“Mr.nobody”}%

首先新建一个 Maven 工程(当然也可以其他类型例如 Gradle 工程),在 pom.xml 文件中引入如下依赖。fastjson 依赖是我们业务用到将 Java 对象转换为 JSON 字符串;spring-boot-configuration-processor 依赖是可选的,加入此依赖主要是打包时,自动生成配置元信息文件 META-INF/spring-configuration-metadata.json,并放入到 jar 中。方便使用者了解到一些配置元信息。

<?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”>

4.0.0

com.nobody

myjson-spring-boot-starter

0.0.1-SNAPSHOT

myjson-spring-boot-starter

Demo project for Spring Boot Starter

<java.version>1.8</java.version>

org.springframework.boot

spring-boot-starter

2.3.8.RELEASE

org.springframework.boot

spring-boot-configuration-processor

2.3.8.RELEASE

true

com.alibaba

fastjson

1.2.73

org.springframework.boot

spring-boot-autoconfigure

2.3.8.RELEASE

业务处理类,实现 Java 对象转换为带有指定前后缀的 JSON 字符串。

package com.nobody.myjson.service;

import com.alibaba.fastjson.JSON;

/**

  • @Description 业务处理类

  • @Author Mr.nobody

  • @Date 2021/2/27

  • @Version 1.0

*/

public class MyJsonService {

// 前缀

private String prefixName;

// 后缀

private String suffixName;

/**

  • 将Java对象转为带有指定前后缀的JSON字符串

  • @param o 需要转换的Java对象

  • @return 转换后的字符串

*/

public String objectToMyJson(Object o) {

return prefixName + JSON.toJSONString(o) + suffixName;

}

public String getPrefixName() {

return prefixName;

}

public void setPrefixName(String prefixName) {

this.prefixName = prefixName;

}

public String getSuffixName() {

return suffixName;

}

public void setSuffixName(String suffixName) {

this.suffixName = suffixName;

}

}

配置类,定义需要的配置信息和默认配置项,并指明关联配置文件的配置项前缀。它可以把相同前缀的配置信息通过配置项名称映射成实体类的属性中。

package com.nobody.myjson.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**

  • @Description 配置类(类名一般为模块名+Properties) nobody.json为Starter使用者通过yml配置文件动态修改属性值的变量名前缀

  • @Author Mr.nobody

  • @Date 2021/2/27

  • @Version 1.0

*/

@ConfigurationProperties(prefix = “nobody.json”)

public class MyJsonProperties {

// Starter使用者没在配置文件中配置prefixName属性的值时的默认值

public static final String DEFAULT_PREFIX_NAME = “@”;

// Starter使用者没在配置文件中配置suffixName属性的值时的默认值

public static final String DEFAULT_SUFFIX_NAME = “@”;

private String prefixName = DEFAULT_PREFIX_NAME;

private String suffixName = DEFAULT_SUFFIX_NAME;

public String getPrefixName() {

return prefixName;

}

public void setPrefixName(String prefixName) {

this.prefixName = prefixName;

}

public String getSuffixName() {

return suffixName;

}

public void setSuffixName(String suffixName) {

this.suffixName = suffixName;

}

}

自动装配类,使用 @Configuration 和 @Bean 来进行自动装配,注入 Spring 容器中。

package com.nobody.myjson.config;

import com.nobody.myjson.service.MyJsonService;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

  • @Description 自动装配类

  • @Author Mr.nobody

  • @Date 2021/2/27

  • @Version 1.0

*/

@Configuration // 标识此类是配置类

@ConditionalOnClass(MyJsonService.class) // 表示只有指定的class在classpath上时才能被注册

@EnableConfigurationProperties(MyJsonProperties.class) // 激活@ConfigurationProperties

public class MyJsonConfiguration {

private MyJsonProperties myJsonProperties;

// 自动注入配置类

public MyJsonConfiguration(MyJsonProperties myJsonProperties) {

this.myJsonProperties = myJsonProperties;

}

// 创建MyJsonService对象,注入到Spring容器中

@Bean

@ConditionalOnMissingBean(MyJsonService.class) // 当容器没有此bean时,才注册

public MyJsonService myJsonService() {

MyJsonService myJsonService = new MyJsonService();

myJsonService.setPrefixName(myJsonProperties.getPrefixName());

myJsonService.setSuffixName(myJsonProperties.getSuffixName());

return myJsonService;

}

}

src/main/resources/META-INF目录下新建 spring.factories 文件,输入以下内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

com.nobody.myjson.config.MyJsonConfiguration

SpringBoot 项目启动时,类加载器会从 META-INF / spring.factories 加载给定类型的工厂实现的完全限定类名。也就是说类加载器得到工程中所有 jar 包中的 META-INF/spring.factories 文件资源,从而得到了一些包括自动配置相关的类的集合,然后将它们实例化,放入 Spring 容器中。

最终项目结构如下:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

笔者已经把面试题和答案整理成了面试专题文档

image

image

image

image

image

image

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
mages/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

最后

笔者已经把面试题和答案整理成了面试专题文档

[外链图片转存中…(img-Eu88gREZ-1713694764288)]

[外链图片转存中…(img-c92KnDhm-1713694764289)]

[外链图片转存中…(img-Q62AXatQ-1713694764289)]

[外链图片转存中…(img-So7MhA5h-1713694764290)]

[外链图片转存中…(img-1n5uh3DF-1713694764290)]

[外链图片转存中…(img-xwsgRc3m-1713694764290)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值