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

2020-02-29  本文已影响0人  kikop

自定义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;

/**

*/

@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;

/**

*/

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;

/**

*/

// 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>

上一篇下一篇

猜你喜欢

热点阅读