Enseñarle cómo personalizar su propio análisis de código fuente del componente SpringBoot Starter

Sabemos que SpringBoot Starter también es el iniciador. Es una gran ventaja de la creación de componentes de SpringBoot. Sobre la base de esta idea, sobre la base de esta idea, SpringBoot se ha vuelto muy poderoso, y el oficial nos proporciona muchos arrancadores listos para usar.

Spring Boot Starter es una característica importante de Spring Boot, que tiene las siguientes ventajas:

  1. Administración de dependencias : Starter maneja automáticamente las dependencias del proyecto, de modo que los desarrolladores no necesitan agregar y administrar manualmente cada dependencia.

  2. Configuración automática : Starter proporciona un método de configuración automática, que puede configurar automáticamente las aplicaciones de Spring de acuerdo con su classpath y las propiedades que defina.

  3. Desarrollo simplificado : al proporcionar iniciadores de varios servicios (como base de datos, seguridad, caché, etc.), el proceso de desarrollo se simplifica enormemente.

  4. Reduzca el código repetitivo : gracias a la configuración automática y la gestión de dependencias de Starter, los desarrolladores pueden centrarse en la lógica empresarial en lugar de la configuración y el código de infraestructura.

  5. Creación rápida de prototipos : use Starter para crear rápidamente prototipos que funcionen.

  6. Fácil de entender y usar : uno de los objetivos de diseño de Spring Boot Starter es permitir que los desarrolladores no profesionales comiencen rápidamente.

  7. Apoyo de la comunidad : además de los Starters proporcionados oficialmente, también hay una gran cantidad de Starters proporcionados por la comunidad que pueden satisfacer diversas necesidades específicas.

Ahora le enseñaré cómo empaquetar su propio iniciador para hacer sus propios componentes springboot. Por supuesto, también puede publicar su propio iniciador en el almacén central de maven para que todos lo usen.

Análisis del propio Starter de SpringBoot

Tomemos como ejemplo la carga automática de WebMvcAutoConfiguration

Existe un requisito para que las clases de configuración automática puedan cargarse. El resultado del análisis del código fuente es que se debe realizar la siguiente configuración en \META-INF\spring.factories

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

De esta manera, cuando se inicia SpringBoot, encontrará nuestra introducción, el iniciador encuentra \META-INF\spring.factoriesel archivo de propiedades, encuentra la ruta de clase que debe cargarse y configurarse automáticamente, y luego lo inyecta automáticamente en el contenedor Spring IOC para nosotros, y nosotros puede usarlo directamente en el proyecto.

La carga automática aquí también depende de algunas anotaciones como:

@Configuration // 指定这个类是个配置类
@ConditionalOnXXX // 在指定条件成立的情况下自动配置类生效
@AutoConfigureOrder //配置类顺序
@AutoConfigureAfter // 在哪个配置类之后
@Bean //给容器中添加组件

@ConfigurationProperties //结合相关的XXXProperties类 来绑定相关的配置
@EnableConfigurationProperties // 让XXXProperties加入到容器中,别人就可以自动装配

Personaliza tu propio arrancador

Después de analizar el iniciador oficial de SpringBoot, personalizamos nuestro propio iniciador (lo copiamos)

Convenciones de nombres

consejos de configuración

Si en el archivo de propiedades personalizadas, se debe introducir el aviso inteligente de IDEA

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

definir arranque

Aquí tomo un iniciador SpringBoot que resume el paquete del proyecto ya que encapsulé y resumí mi trabajo como ejemplo.

 <dependency>
            <groupId>cn.soboys</groupId>
            <artifactId>rest-api-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>

Es el comienzo empaquetado por mí mismo. El repositorio central ha sido liberado.

Las características actuales de la versión actualizada 1.3.0 son las siguientes

  1. Admite la configuración con un solo clic para personalizar la devolución del formato uniforme de la API RestFull
  2. Admite la internacionalización de errores de la API RestFull
  3. Admite manejo de excepciones globales, procesamiento de verificación de parámetros globales
  4. Encapsulación de herramientas de afirmación de errores comerciales, siguiendo el principio de devolver los errores primero
  5. paquete de trabajo redis. Admite todas las herramientas de operación clave
  6. RestTemplate encapsula la herramienta de solicitud POST, GET
  7. Integración de registros. Personalice la ruta del registro, clasifíquelo según el nivel del registro, admita la compresión y la segmentación del tamaño del archivo. mostrar por tiempo
  8. La biblioteca de herramientas integra lombok, hutool, commons-lang3 y guava. No es necesario importarlos individualmente
  9. Generación de código mybatisPlus integrada con un solo clic

rest-api-spring-boot-starter
Dirección del almacén
github

  1. Archivo de propiedades de configuración personalizado
rest-api:
  enabled: false
  logging:
    path: ./logs
  i18n:
    # 若前端无header传参则返回中文信息
    i18n-header: Lang
    default-lang: cn
    message:
      # admin
      internal_server_error:
        en: Internal Server Error
        cn: 系统错误
      not_found:
        en: Not Found
        cn: 请求资源不存在

  1. Definir clase de configuración de propiedad
package cn.soboys.restapispringbootstarter.i18n;


import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;


import java.util.Map;
import java.util.Optional;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/6/26 11:55
 * @webSite https://github.com/coder-amiao
 */
//@PropertySource(value = "classpath:i18n.yaml", factory = YamlPropertySourceFactory.class)
@Configuration
@ConfigurationProperties(prefix = "rest-api.i18n")
@Data
public class I18NMessage {
    
    
    /**
     * message-key:<lang:message>
     */
    private Map<String, Map<String, String>> message;
    /**
     * Default language setting (Default "cn").
     */
    private String defaultLang = "cn";


    private String i18nHeader = "Lang";


    /**
     * get i18n message
     *
     * @param key
     * @param language
     * @return
     */
    public String message(I18NKey key, String language) {
    
    
        return Optional.ofNullable(message.get(key.key()))
                .map(map -> map.get(language == null ? defaultLang : language))
                .orElse(key.key());
    }

    /**
     * get i18n message
     *
     * @param key
     * @param language
     * @return
     */
    public String message(String key, String language) {
    
    
        return Optional.ofNullable(message.get(key))
                .map(map -> map.get(language == null ? defaultLang : language))
                .orElse(key);
    }

}

  1. Defina BeanAutoConfiguration para cargar automáticamente las clases de configuración
package cn.soboys.restapispringbootstarter.config;

import cn.soboys.restapispringbootstarter.ApplicationRunner;
import cn.soboys.restapispringbootstarter.ExceptionHandler;
import cn.soboys.restapispringbootstarter.ResultHandler;
import cn.soboys.restapispringbootstarter.aop.LimitAspect;
import cn.soboys.restapispringbootstarter.i18n.I18NMessage;
import cn.soboys.restapispringbootstarter.utils.RedisTempUtil;
import cn.soboys.restapispringbootstarter.utils.RestFulTemp;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.List;

/**
 * @author 公众号 程序员三时
 * @version 1.0
 * @date 2023/6/27 11:36
 * @webSite https://github.com/coder-amiao
 */
@Configuration
@ConditionalOnProperty(name = "rest-api.enabled", havingValue = "true")
public class BeanAutoConfiguration {
    
    


    @Bean
    public I18NMessage i18NMessage() {
    
    
        return new I18NMessage();
    }

    @Bean
    public ResultHandler resultHandler() {
    
    
        return new ResultHandler();
    }

    @Bean
    public ExceptionHandler exceptionHandler() {
    
    
        return new ExceptionHandler();
    }

    @Bean
    public StartupApplicationListener startupApplicationListener() {
    
    
        return new StartupApplicationListener();
    }


    @Bean
    public RestApiProperties restApiProperties() {
    
    
        return new RestApiProperties();
    }

    @Bean
    public RestApiProperties.LoggingProperties loggingProperties(RestApiProperties restApiProperties) {
    
    
        return restApiProperties.new LoggingProperties();
    }

    @Bean
    public ApplicationRunner applicationRunner() {
    
    
        return new ApplicationRunner();
    }




    /**
     * restTemplate 自动注入
     */
    @Configuration
    @ConditionalOnProperty(name = "rest-api.enabled", havingValue = "true")
    class RestTemplateConfig {
    
    
        /**
         * 第三方请求要求的默认编码
         */
        private final Charset thirdRequest = Charset.forName("utf-8");

        @Bean
        public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
    
    
            RestTemplate restTemplate = new RestTemplate(factory);
            // 处理请求中文乱码问题
            List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
            for (HttpMessageConverter<?> messageConverter : messageConverters) {
    
    
                if (messageConverter instanceof StringHttpMessageConverter) {
    
    
                    ((StringHttpMessageConverter) messageConverter).setDefaultCharset(thirdRequest);
                }
                if (messageConverter instanceof MappingJackson2HttpMessageConverter) {
    
    
                    ((MappingJackson2HttpMessageConverter) messageConverter).setDefaultCharset(thirdRequest);
                }
                if (messageConverter instanceof AllEncompassingFormHttpMessageConverter) {
    
    
                    ((AllEncompassingFormHttpMessageConverter) messageConverter).setCharset(thirdRequest);
                }
            }
            return restTemplate;
        }

        @Bean
        public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
    
    
            SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
            factory.setConnectTimeout(15000);
            factory.setReadTimeout(5000);
            return factory;
        }


        @Bean
        public RestFulTemp restFulTemp() {
    
    
            return new RestFulTemp();
        }

    }

}
  1. Autocableado
    en proyecto

spring.factoriesConfigúrate para cargar la clase de configuración

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.soboys.restapispringbootstarter.config.BeanAutoConfiguration,\
cn.soboys.restapispringbootstarter.config.BeanAutoConfiguration.RestTemplateConfig,\
cn.soboys.restapispringbootstarter.utils.RedisTempUtil\

Ampliando el pensamiento, podemos ver que muchos de los estados oficiales de SpringBoot son similares a @Enablexxxlas anotaciones
. My rest-api-spring-boot-starter1.3.0 ya se implementó y todas las funciones se pueden usar directamente en la clase de inicio o la clase de configuración sin configurar una línea en application.propertiesEnableRestFullApi

El uso perfecto del documento me puede ver

SpringBoot define un marco de respuesta de API Restful elegante y globalmente unificado Finaliza el capítulo Sprinkle Encapsula el componente de inicio

Este artículo

En este punto, la definición del iniciador está terminada y el siguiente paso es empaquetarlo y publicarlo en el almacén central de maven .

Continuaré compartiendo en el próximo artículo.

Deja tus pensamientos y presta atención a los programadores públicos durante tres horas

Continúe produciendo contenido de alta calidad y espero brindarle un poco de inspiración y ayuda.

Supongo que te gusta

Origin blog.csdn.net/u011738045/article/details/131589843
Recomendado
Clasificación