美文网首页
2020-02-29_自定义hello-spring-boote

2020-02-29_自定义hello-spring-boote

作者: kikop | 来源:发表于2020-02-29 20:41 被阅读0次

    自定义hello-spring-booter-starter

    1概述

    1.1 SpringBoot核心原理

    springboot的核心有如下四点:

    ① 起步依赖

    核心是依赖传递,官方集成的第三方框架,从而实现版本管理

    ② 自动配置管理

    通过springboot自动配置管理特性将其实例化到(自定义)类中程序启动时,向Spring容器中导入很多配置,代替繁琐的xml或注入Bean。注解中加入EnableConfigurationProperties,application.yml中的所有配置文件都会指向实体类。如server.port对应的实体类ServerProperties(扫描包路径为:org.springframework.boot.autoconfigure),

    @ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)

    public class ServerProperties {

    ③ 运行监控管理Actuator

    ④ 命令行工具cli

    可以使用SpringBoot快速的开发基于Spring框架的项目。由于围绕SpringBoot存在很多开箱即用的Starter依赖,使得我们在开发业务代码时能够非常方便的、不需要过多关注框架的配置,而只需要关注业务即可。

    1.2 常用的几个注解说明

    @Configuration:表明此类是一个配置类,将变为一个bean被spring进行管理。

    @EnableConfigurationProperties:启用属性配置,将读取HelloServiceProperties里面的属性。

    @ConditionalOnClass:当类路径下面有HelloServiceConfiguration此类时,自动配置。

    @ConditionalOnProperty:判断指定的属性是否具备指定的值。

    @ConditionalOnMissingBean:当容器中没有指定bean是,创建此bean。

    @ConditionalOnBean:当容器中有指定的Bean的条件下

    @ConditionalOnClass:当类路径下有指定的类的条件下

    @ConditionalOnExpression:基于SpEL表达式作为判断条件

    @ConditionalOnJava:基于JVM版本作为判断条件

    @ConditionalOnJndi:在JNDI存在的条件下查找指定的位置

    @ConditionalOnMissingBean:当容器中没有指定Bean的情况下

    @ConditionalOnMissingClass:当类路径下没有指定的类的条件下

    @ConditionalOnNotWebApplication:当前项目不是Web项目的条件下

    @ConditionalOnProperty:指定的属性是否有指定的值

    @ConditionalOnResource:类路径下是否有指定的资源

    @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean @ConditionalOnWebApplication:当前项目是Web项目的条件下

    1.3 @EnableAutoC vs @ImportAutoConfiguration

    使用@EnableAutoConfiguration时会扫描整个类路径下,包括依赖引入的jar包所有的自动配置类(被注解了@Configuration的类),尝试进行自动配置。比如,tomcat-embedded.jar。

    而@ImportAutoConfiguration只运行在你注解中提供的配置类。

    下面是一个Spring Boot入口方法中使用@ImportAutoConfiguration的列子:

    @ComponentScan("path.to.your.controllers")

    @ImportAutoConfiguration({

    WebMvcAutoConfiguration.class,

    DispatcherServletAutoConfiguration.class,

    EmbeddedServletContainerAutoConfiguration.class,

    ServerPropertiesAutoConfiguration.class,

    HttpMessageConvertersAutoConfiguration.class

    })

    public class App {

    image.png

    2自定义boot-starter

    遵循springboot官方建议对于非官方的starter命名方式为xxx-spring-boot-starter,所以本工程名为hello-spring-boot-starter。

    2.1实现原理

    我们知道使用一个公用的starter的时候,只需要将相应的依赖添加的Maven的配置文件当中即可,免去了自己需要引用很多依赖类,并且SpringBoot会自动进行类的自动配置。那么 SpringBoot 是如何知道要实例化哪些类,并进行自动配置的呢,分如下三步骤:

    1.SpringBoot 在启动时会去依赖的starter包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的Jar包去扫描项目所依赖的Jar包,这类似于 Java 的 SPI 机制。

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

    com.kikop.boot.HelloServiceAutoConfiguration

    2.根据spring.factories配置加载AutoConfiguration类。

    3.根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context 上下文当中。我们也可以使用@ImportAutoConfiguration({HelloServiceAutoConfiguration.class}) 指定自动配置哪些类。

    2.2实现步骤

    2.2.1创建maven

    <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.kikop.boot</groupId>
    
    <artifactId>hello-spring-boot-starter</artifactId>
    
    <version>1.0-SNAPSHOT</version>
    
    <packaging>jar</packaging>
    
    <dependencies>
    
        <!--业务系统中添加-->
    
        <!--作用是编译时生成 spring-configuration-metadata.json ,-->
    
        <!--此文件主要给IDE使用。如当配置此jar相关配置属性在 application.yml ,-->
    
        <!--你可以用ctlr+鼠标左键点击属性名,IDE会跳转到你配置此属性的类中。-->
    
        <!--<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-autoconfigure</artifactId>
    
            <version>2.1.4.RELEASE</version>
    
        </dependency>
    
    </dependencies>
    
    <build>
    
        <plugins>
    
            <plugin>
    
                <groupId>org.springframework.boot</groupId>
    
                <artifactId>spring-boot-maven-plugin</artifactId>
    
            </plugin>
    
        </plugins>
    
    </build>
    

    </project>

    2.2.2配置文件读取类

    package com.kikop.boot.properties;

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

    /**

    • @author kikop

    • @version 1.0

    • @project Name: hello-spring-bootstarter

    • @file Name: HelloServiceProperties

    • @desc 功能描述 配置文件读取类

    • 对应yml配置文件总的属性,配置此注解可以自动导入application.properties配置文件中的属性

    • @date 2020/2/20

    • @time 7:33

    • @by IDE: IntelliJ IDEA

    */

    @ConfigurationProperties(prefix = HelloServiceProperties.PREFIX,ignoreUnknownFields = true)

    public class HelloServiceProperties {

    public static final String PREFIX = "com.kikop.boot";
    
    // 定义jar包中默认的配置属性:name
    
    private String name = "hello";
    
    // 定义jar包中默认的配置属性:hobby
    
    private String hobby = "springboot";
    
    // 定义jar包中默认的配置属性:place
    
    private String place="nj";
    
    public String getPlace() {
    
        return place;
    
    }
    
    public void setPlace(String place) {
    
        this.place = place;
    
    }
    
    public String getName() {
    
        return name;
    
    }
    
    public void setName(String name) {
    
        this.name = name;
    
    }
    
    public String getHobby() {
    
        return hobby;
    
    }
    
    public void setHobby(String hobby) {
    
        this.hobby = hobby;
    
    }
    

    }

    2.2.3业务实体类

    package com.kikop.boot.entity;

    import org.springframework.util.StringUtils;

    /**

    • @author kikop

    • @version 1.0

    • @project Name: hello-spring-bootstarter

    • @file Name: HelloServiceInfo

    • @desc 功能描述 Starter要实现的功能

    • 已基于业务转化的包装类

    • @date 2020/2/20

    • @time 7:36

    • @by IDE: IntelliJ IDEA

    */

    public class HelloServiceInfo {

    //姓名
    
    private String name;
    
    //爱好(多个逗号分隔)
    
    private String hobby;
    
    //住址
    
    private String place;
    
    public String getPlace() {
    
        return place;
    
    }
    
    public void setPlace(String place) {
    
        this.place = place;
    
    }
    
    public String getName() {
    
        return "name is " + name;
    
    }
    
    public String getHobby() {
    
        return "hobby is " + hobby;
    
    }
    
    public void setName(String name) {
    
        this.name = name;
    
    }
    
    public void setHobby(String hobby) {
    
        this.hobby = hobby;
    
    }
    
    public String[] split(String separatorChar) {
    
        return StringUtils.split(this.getHobby(), separatorChar);
    
    }
    
    @Override
    
    public String toString() {
    
        return "HelloServiceInfo{" +
    
                "name='" + name + '\'' +
    
                ", hobby='" + hobby + '\'' +
    
                ", place='" + place + '\'' +
    
                '}';
    
    }
    

    }

    2.2.4自动配置类

    package com.kikop.boot;

    import com.kikop.boot.entity.HelloServiceInfo;

    import com.kikop.boot.properties.HelloServiceProperties;

    import org.springframework.beans.factory.annotation.Autowired;

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

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

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

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

    import org.springframework.context.annotation.Bean;

    import org.springframework.context.annotation.Configuration;

    /**

    • @author kikop

    • @version 1.0

    • @project Name: hello-spring-bootstarter

    • @file Name: HelloServiceAutoConfiguration

    • @desc 功能描述 自动配置类

    • @date 2020/2/20

    • @time 7:37

    • @by IDE: IntelliJ IDEA

    */

    // 1.Configuration 表明此类是一个配置类,将变为一个bean被spring进行管理

    @Configuration

    // 2.当类路径下面有HelloServiceInfo此类时,自动配置

    @ConditionalOnClass(HelloServiceInfo.class)

    // 3.启用属性配置,将读取 HelloServiceProperties 里面的属性

    @EnableConfigurationProperties(HelloServiceProperties.class)

    //// 4.判断指定的属性是否具备指定的值(放类上)

    //@ConditionalOnProperty(prefix = "com.kikop.boot", value = "enabled", matchIfMissing = true)

    public class HelloServiceAutoConfiguration {

    /**
    
     * 注入读取的 HelloServiceProperties
    
     */
    
    @Autowired
    
    private HelloServiceProperties helloServiceProperties;
    
    /**
    
     * 注入Bean,已基于业务转化的包装类
    
     * @return
    
     */
    
    @Bean
    
    @ConditionalOnMissingBean(HelloServiceInfo.class)
    
    // 4.判断指定的属性是否具备指定的值(放Bean上)
    
    // 当配置文件中 com.kikop.boot.enabled=true
    
    @ConditionalOnProperty(prefix = "com.kikop.boot", value = "enabled",matchIfMissing = true)
    
    public HelloServiceInfo helloServiceInfo() {
    
        HelloServiceInfo helloServiceInfo=new HelloServiceInfo();
    
        helloServiceInfo.setName(helloServiceProperties.getName());
    
        helloServiceInfo.setHobby(helloServiceProperties.getHobby());
    
        helloServiceInfo.setPlace(helloServiceProperties.getPlace());
    
        return helloServiceInfo;
    
    }
    

    }

    2.2.5spring.factories

    文件位置:resorces\META-INF\spring.factories

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

    com.kikop.boot.HelloServiceAutoConfiguration

    2.3测试

    2.3.1加入依赖

    <dependency>

    <groupId>com.kikop.boot</groupId>
    
    <artifactId>hello-spring-boot-starter</artifactId>
    
    <version>1.0-SNAPSHOT</version>
    

    </dependency>

    <dependency>

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

    </dependency>

    2.3.2 controller

    @Autowired

    HelloServiceInfo helloServiceInfo;

    @RequestMapping(value = "/hello")

    public String hello() {

    return helloServiceInfo.toString();
    

    }

    2.3.3 application.yml

    com:

    kikop:

    boot:
    

    enable: true

      name: kikop11
    
      hobby: tabletennis
    
      place: nj
    

    2.3.4调用

    http://localhost:8762/hello

    HelloServiceInfo{name='kikop', hobby='tabletennis', place='nj'}

    参考

    1. Springcloud

    <u>https://spring.io/projects/spring-cloud</u>

    <u>https://start.spring.io/</u>

    1. SpringBoot启动过程分析

    <u>https://www.jianshu.com/p/603d125f21b3</u>

    1. SpringBoot启动类图

    <u>https://www.processon.com/view/link/59812124e4b0de2518b32b6e</u>

    1. 使用springboot自定义starter实例1

    <u>https://blog.csdn.net/qq_21150865/article/details/83504780</u>

    1. 编写自己的SpringBoot-starter

    <u>https://www.cnblogs.com/yuansc/p/9088212.html</u>

    相关文章

      网友评论

          本文标题:2020-02-29_自定义hello-spring-boote

          本文链接:https://www.haomeiwen.com/subject/hodvhhtx.html