• SpringBoot应用篇(一):自定义starter


    一、码前必备知识

    1、SpringBoot starter机制

      SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。

    2、为什么要自定义starter

      在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,麻烦至极。如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,复用的时候只需要将其在pom中引用依赖即可,SpringBoot为我们完成自动装配,简直不要太爽。

    3、自定义starter的案例

      以下案例由笔者工作中遇到的部分场景

      ▲ 动态数据源。

      ▲ 登录模块。

      ▲ 基于AOP技术实现日志切面。

      。。。。。。

    4、自定义starter的命名规则

      SpringBoot提供的starter以spring-boot-starter-xxx的方式命名的。官方建议自定义的starter使用xxx-spring-boot-starter命名规则。以区分SpringBoot生态提供的starter。

    5、代码地址

      https://github.com/hello-shf/demo-spring-boot-starter.git simple分支哦

    二、starter的实现方法

    1、新建一个工程

      命名为demo-spring-boot-starter

      下图为工程目录结构

      

    2、pom依赖

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     4     <modelVersion>4.0.0</modelVersion>
     5     <parent>
     6         <groupId>org.springframework.boot</groupId>
     7         <artifactId>spring-boot-starter-parent</artifactId>
     8         <version>2.1.4.RELEASE</version>
     9     </parent>
    10     <groupId>com.demo</groupId>
    11     <artifactId>demo-spring-boot-starter</artifactId>
    12     <version>0.0.1-RELEASE</version>
    13     <name>demo-spring-boot-starter</name>
    14     <description>Demo project for Spring Boot</description>
    15 
    16     <properties>
    17         <java.version>1.8</java.version>
    18     </properties>
    19 
    20     <dependencies>
    21 
    22         <dependency>
    23             <groupId>org.springframework.boot</groupId>
    24             <artifactId>spring-boot-configuration-processor</artifactId>
    25             <optional>true</optional>
    26         </dependency>
    27 
    28         <dependency>
    29             <groupId>org.springframework.boot</groupId>
    30             <artifactId>spring-boot-starter</artifactId>
    31         </dependency>
    32     </dependencies>
    33 </project>

    3、定义一个实体类映射配置信息

     @ConfigurationProperties(prefix = "demo") 它可以把相同前缀的配置信息通过配置项名称映射成实体类,比如我们这里指定 prefix = "demo" 这样,我们就能将以demo为前缀的配置项拿到了。
    ps:其实这个注解很强大,它不但能映射成String或基本类型的变量。还可以映射为List,Map等数据结构。
     1 package com.demo.starter.properties;
     2 
     3 import org.springframework.boot.context.properties.ConfigurationProperties;
     4 
     5 /**
     6  * 描述:配置信息 实体
     7  *
     8  * @Author shf
     9  * @Date 2019/5/7 22:08
    10  * @Version V1.0
    11  **/
    12 @ConfigurationProperties(prefix = "demo")
    13 public class DemoProperties {
    14     private String sayWhat;
    15     private String toWho;
    16 
    17     public String getSayWhat() {
    18         return sayWhat;
    19     }
    20 
    21     public void setSayWhat(String sayWhat) {
    22         this.sayWhat = sayWhat;
    23     }
    24 
    25     public String getToWho() {
    26         return toWho;
    27     }
    28 
    29     public void setToWho(String toWho) {
    30         this.toWho = toWho;
    31     }
    32 }

    4、定义一个Service

     1 package com.demo.starter.service;
     2 
     3 /**
     4  * 描述:随便定义一个Service
     5  *
     6  * @Author shf
     7  * @Date 2019/5/7 21:59
     8  * @Version V1.0
     9  **/
    10 public class DemoService {
    11     public String sayWhat;
    12     public String toWho;
    13     public DemoService(String sayWhat, String toWho){
    14         this.sayWhat = sayWhat;
    15         this.toWho = toWho;
    16     }
    17     public String say(){
    18         return this.sayWhat + "!  " + toWho;
    19     }
    20 }

    5,定义一个配置类

    这里,我们将DemoService类定义为一个Bean,交给Ioc容器。

    ▲  @Configuration 注解就不多说了。

    ▲  @EnableConfigurationProperties 注解。该注解是用来开启对3步骤中 @ConfigurationProperties 注解配置Bean的支持。也就是@EnableConfigurationProperties注解告诉Spring Boot 能支持@ConfigurationProperties。

    当然了,也可以在 @ConfigurationProperties 注解的类上添加 @Configuration 或者  @Component 注解

    ▲  @ConditionalOnProperty 注解控制 @Configuration 是否生效。简单来说也就是我们可以通过在yml配置文件中控制 @Configuration 注解的配置类是否生效。

     1 package com.demo.starter.config;
     2 
     3 import com.demo.starter.properties.DemoProperties;
     4 import com.demo.starter.service.DemoService;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
     7 import org.springframework.boot.context.properties.EnableConfigurationProperties;
     8 import org.springframework.context.annotation.Bean;
     9 import org.springframework.context.annotation.Configuration;
    10 
    11 /**
    12  * 描述:配置类
    13  *
    14  * @Author shf
    15  * @Date 2019/5/7 21:50
    16  * @Version V1.0
    17  **/
    18 @Configuration
    19 @EnableConfigurationProperties(DemoProperties.class)
    20 @ConditionalOnProperty(
    21         prefix = "demo",
    22         name = "isopen",
    23         havingValue = "true"
    24 )
    25 public class DemoConfig {
    26     @Autowired
    27     private DemoProperties demoProperties;
    28 
    29     @Bean(name = "demo")
    30     public DemoService demoService(){
    31         return new DemoService(demoProperties.getSayWhat(), demoProperties.getToWho());
    32     }
    33 }

     6、最重要的来了

    如图,新建META-INF文件夹,然后创建spring.factories文件,

     在该文件中加入如下配置,该配置指定上步骤中定义的配置类为自动装配的配置。(笔者努力最近把自动装配的博客写出来)

    1 #-------starter自动装配---------
    2 org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.demo.starter.config.DemoConfig

     7、测试

    在demo-spring-boot-starter工程中执行mvn clean install 一个自定义的starter新鲜出炉。

    新建测试工程

    引入starter依赖

    1         <dependency>
    2             <groupId>com.demo</groupId>
    3             <artifactId>demo-spring-boot-starter</artifactId>
    4             <version>0.0.1-RELEASE</version>
    5         </dependency>

    配置文件

    1 demo.isopen=true
    2 demo.say-what=hello
    3 demo.to-who=shf

    然后写个测试类。

     1 package com.example.test.controller;
     2 
     3 import com.demo.starter.service.DemoService;
     4 import org.springframework.web.bind.annotation.GetMapping;
     5 import org.springframework.web.bind.annotation.RestController;
     6 
     7 import javax.annotation.Resource;
     8 
     9 /**
    10  * 描述:
    11  *
    12  * @Author shf
    13  * @Description TODO
    14  * @Date 2019/5/13 15:52
    15  * @Version V1.0
    16  **/
    17 @RestController
    18 public class DemoController {
    19     @Resource(name = "demo")
    20     private DemoService demoService;
    21 
    22     @GetMapping("/say")
    23     public String sayWhat(){
    24         return demoService.say();
    25     }
    26     
    27 }

     浏览器

    小小的码农,大大的梦想
  • 相关阅读:
    【Python3之匿名函数及递归】
    【Python3之模块及包的导入】
    :nth-child和:nth-of-type的区别
    JavaScript ES6中export及export default的区别以及import的用法
    vue中npm run dev运行项目不能自动打开浏览器! 以及 webstorm跑vue项目jshint一直提示错误问题的解决方法!
    SEO优化之HTML代码优化最重要的5个标签
    清除浮动小记,兼容Ie6,7
    JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承
    面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式
    纯CSS实现垂直居中的几种方法
  • 原文地址:https://www.cnblogs.com/hello-shf/p/10864977.html
Copyright © 2020-2023  润新知