当前位置:   article > 正文

自定义 Spring Boot Starter_毕业论文基于springboot的数据库连接模块的创建的类怎么声明

毕业论文基于springboot的数据库连接模块的创建的类怎么声明

一、引言

什么是Spring Boot Starter呢?我们直接来看看官网是怎么介绍的吧。

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.
  • 1

我们以上述官网的例子来进行说明比如说我们需要在Spring 中适应JPA来操作数据库。在没有springBoot-starter之前,我们需要引入jpa的步骤

  • 通过maven 引入 jdbc 的依赖、以及 jpa 相关的各种依赖

  • 编写jpa相关的配置文件

  • 网上各种查询找资料进行调试,调试的过程对于新手可能会有点奔溃会遇到各种奇奇怪怪的问题,jar包冲突啊,这个jar包下载不下来,缺少某个jar包。

  • 终于在经历千辛万苦,哼次哼次的解决各种问题之后终于把项目跑起来了,然后把这次整合jpa遇到的问题,以及整合的步骤都一一的详细记录下来。方便下次在需要整合jpa的时候直接copy就好了。我们以前在没有starter之前是不是都是这么玩的。这样的缺点是不是也非常显著,比如过程复杂、需要不停的粘贴复制(不过这是程序员经常干的事情了,也不在乎多一两次了)、整合其它组件到自己的项目变的困难,效率低下。

二、SpringBoot Starter 的出现

我们可以看下SpringBoot 现在都为我们提供有哪些starter,这截图了部分starter,更多的请点击https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters
在这里插入图片描述

  • starter的实现:虽然我们每个组件的starter实现各有差异,但是它们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfiguration
  • 因为SpringBoot提倡“「约定大于配置」”这一理念,所以我们使用ConfigurationProperties来保存我们的配置,并且这些配置都可以有一个默认值,即在我们没有主动覆写原始配置的情况下,默认值就会生效。
  • 除此之外,starter的ConfigurationProperties还使得所有的配置属性被聚集到一个文件中(一般在resources目录下的application.properties),这样我们就告别了Spring项目中XML地狱。starter的出现帮把我们把各种复杂的配置都封装起来了,让我们真正的可以达到了开箱即用。不仅降低了我们使用它的门槛,并且还大大提高了我们的开发效率。
  • 整体逻辑
    在这里插入图片描述

三、实现自己的 SpringBoot Starter

  1. 命名规范
    在maven中,groupId代表着姓氏,artifactId代表着名字。Spring Boot也是有一个命名的建议的。所以名字是不能够随随便便取得,可以按照官方的建议来取
What’s in a nameAll official starters follow a similar naming pattern; spring-boot-starter-*, where * is
 a particular type of application. This naming structure is intended to help when you need to find a 
 starter. The Maven integration in many IDEs lets you search dependencies by name. For example, with the 
 appropriate Eclipse or STS plugin installed, you can press ctrl-space in the POM editor and type 
 “spring-boot-starter” for a complete list.As explained in the “Creating Your Own Starter” section, third
  party starters should not start with spring-boot, as it is reserved for official Spring Boot artifacts.
   Rather, a third-party starter typically starts with the name of the project. For example, a third-
   party starter project called thirdpartyproject would typically be named thirdpartyproject-spring-boot-
   starter.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

大概意思是:

  • 官方的 starter 的命名格式为 spring-boot-starter-{xxxx}比如spring-boot-starter-activemq
  • 第三方我们自己的命名格式为{xxxx}-spring-boot-starter。比如mybatis-spring-boot-starter。
  • 如果我们忽略这种约定,是不是会显得我们写的东西不够“专业“。
  1. 自定义一个 Starter
    下面我们就来实现一个自定义的发送短信的 starter,命名为sms-spring-boot-starter。
  • 编写配置文件匹配类

发短信我们需要配置一些账号信息,不同的短信供应商,账户信息是不一样的,所以我们需要定义一个XXXXProperties 来自动装配这些账户信息。下面我们就以腾讯云和阿里云两家供应商为例;

//配置前缀,区别各个组件的参数
@ConfigurationProperties(prefix = "sms")
@Data
public class SmsProperties {
    private SmsMessage aliyun = new SmsMessage();
    private SmsMessage tencent = new SmsMessage();
    @Data
    public static class SmsMessage{
        /**
         * 用户名
         */
        private String userName;
        /**
         * 密码
         */
        private String passWord;
        /**
         * 秘钥
         */
        private String sign;
        /**
         *
         */
        private String url;
        @Override
        public String toString() {
            return "SmsMessage{" +
                    "userName='" + userName + '\'' +
                    ", passWord='" + passWord + '\'' +
                    ", sign='" + sign + '\'' +
                    ", url='" + url + '\'' +
                    '}';
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 编写自动配置类
@EnableConfigurationProperties(value = SmsProperties.class)
@Configuration
public class SmsAutoConfiguration  {
    /**
     *  阿里云发送短信的实现类
     * @param smsProperties
     * @return
     */
    @Bean
    public AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){
        return new AliyunSmsSenderImpl(smsProperties.getAliyun());
    }
    /**
     * 腾讯云发送短信的实现类
     * @param smsProperties
     * @return
     */
    @Bean
    public TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){
        return new TencentSmsSenderImpl(smsProperties.getTencent());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 编写两个业务类便于测试
@ConditionalOnMissingBean({SmsMessage.class})
public class AliyunSmsSenderImpl implements SmsSender{
    private final SmsMessage smsMessage;
    public AliyunSmsSenderImpl(SmsMessage smsProperties) {
        this.smsMessage = smsProperties;
    }
    @Override
    public boolean send(String message) {
        System.out.println(smsMessage.toString()+"开始发送短信==》短信内容:"+message);
        return true;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 让 starter 生效

starter集成应用有两种方式(被动生效和主动生效):

  • 被动生效:通过SpringBoot的SPI的机制来去加载我们的 starter
    我们需要在META-INF下新建一个spring.factories文件key为org.springframework.boot.autoconfigure.EnableAutoConfiguration, value是我们的SmsAutoConfiguration 全限定名(「记得去除前后的空格,否则会不生效」)。
    在这里插入图片描述
  • 主动生效:前提是先注销spring.factories
    主动生效在starter组件集成到我们的Spring Boot应用时需要主动声明启用该starter才生效,通过自定义一个@Enable注解然后在把自动配置类通过Import注解引入进来
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SmsAutoConfiguration.class})
public @interface EnableSms {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

使用的时候需要在启动类上面开启这个注解即可。
在这里插入图片描述
至此,我们的自定义starter已经写好了,接下来就是打包生成starter.jar。下面是工程完整结构:
在这里插入图片描述
注意,不是传统的可运行jar项目,所以没有主入口

  • pom.xml文件
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cristiano</groupId>
    <artifactId>sms-spring-boot-starter</artifactId>
    <version>0.0.1</version>
    <name>sms-spring-boot-starter</name>
    <description>sms-spring-boot-starter</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--安装到仓库后,引用时不出现 BOOT-INF文件夹(会导致找不到相关类)-->
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

重点注意:如果maven没有这么配置,那么打包成jar的时候,会出现BOOT-INF文件夹,导致使用模块的时候,找不到类,详细参考这篇文章

 <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!--安装到仓库后,引用时不出现 BOOT-INF文件夹(会导致找不到相关类)-->
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述
Lifecycle下install就可以将模块引用到本地仓库了

四、测试Starter

  • 引用
        <dependency>
            <groupId>com.cristiano</groupId>
            <artifactId>sms-spring-boot-starter</artifactId>
            <version>0.0.1</version>
        </dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 启用
@SpringBootApplication
@EnableSms
public class TeststarterApplication {public static void main(String[] args) {
        SpringApplication.run(TeststarterApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 配置(有提示)
    在这里插入图片描述
  • 测试
    在这里插入图片描述
    至此就结束了么?其实上面的例子加不加@EnableSms,都能正常打印信息,因为我们在Starter的spring.factories中已经配置了自动配置类,属于被动加载。

五、插拔式starter(基于主动依赖)

  1. 在SmsAutoConfiguration的原基础上,加上以下注解后,重新install
@EnableConfigurationProperties(value = SmsProperties.class)
@Configuration
public class SmsAutoConfiguration  {
    /**
     *  阿里云发送短信的实现类
     * @param smsProperties
     * @return
     */
    @Bean
    //表示在EnableSms注解存在的情况下,该bean才会被注册
    @ConditionalOnBean(annotation = EnableSms.class)
    public AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){
        return new AliyunSmsSenderImpl(smsProperties.getAliyun());
    }
    /**
     * 腾讯云发送短信的实现类
     * @param smsProperties
     * @return
     */
    @Bean
    public TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){
        return new TencentSmsSenderImpl(smsProperties.getTencent());
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • EnableSms
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SmsAutoConfiguration.class})
public @interface EnableSms {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 主配置类
//不使用@EnableSms
@SpringBootApplication
public class TeststarterApplication {public static void main(String[] args) {
        SpringApplication.run(TeststarterApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到报错,原因是AliyunSmsSenderImpl 没有注册到bean中,所以使用条件注解可以实现starter的插拔式应用
在这里插入图片描述
正式使用

@EnableSms
@SpringBootApplication
public class TeststarterApplication {public static void main(String[] args) {
        SpringApplication.run(TeststarterApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
 //注入AliyunSmsSenderImpl
    @Autowired
    AliyunSmsSenderImpl aliyunSmsSender;
    public void test(){
        aliyunSmsSender.send("from aliyun");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

配置

sms:
  aliyun:
    pass-word: aa
    user-name: aa
    url: www.aliyun.com
    sign: alibaba
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

参考文章
参考文章

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/947761
推荐阅读
相关标签
  

闽ICP备14008679号