springboot中级教程之springboot自定义配置(代码片段)

夜宿山寺 夜宿山寺     2023-01-15     666

关键词:

SpringBoot中级教程之SpringBoot自定义配置(十一)

前言首先力推下我的开源项目

http://git.oschina.net/wangkang_daydayup/swagger-doc 这是一个完全利用spring boot开发的项目,拯救了springfox-swagger污染代码的问题,完全利用java-doc来实现,学习成本几乎是0

1.介绍

在Spring的代码中随处可见的@EnableAutoConfiguration@EnableWebMvc@EnableTransactionManagement这些注解,通过使用这些注解来开启某项功能,下面的
例子就是来讲解如何定义自己的@EnableXXX

使用场景

官方介绍:If you work in a company that develops shared libraries, or if you work on an open-source or commercial library, you might want to develop your own auto-configuration. Auto-configuration classes can be bundled in external jars and still be picked-up by Spring Boot.
Auto-configuration can be associated to a “starter” that provides the auto-configuration code as well as the typical libraries that you would use with it. We will first cover what you need to know to build your own auto-configuration and we will move on to the typical steps required to create a custom starter.

大概意思是这样的:如果你在一个开发共享库的公司,或者是你想开发自己的auto-configuration,也就是说为spring boot开发一些自动配置的模块的时候,这个时候就需要用到这个技术,
完全可以通过一个注解或者引入一个jar包就开启这个功能

2.快速开始

下面是pom的配置 主要核心配置是spring-boot-configuration-processor,这个是用来对注解进行处理的,官方解释是
You can easily generate your own configuration meta-data file from items annotated with @ConfigurationProperties

2.1 首先是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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springboot-11</artifactId>
    <dependencies>
        <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-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.5.4.RELEASE</version>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.2 声明一个注解@EnableDemo

@EnableDemo是自己定义的一个注解,用来启用DemoConfig这个类当中的内容,其实原理跟扫描或者是配置xml是差不多的


@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value =  java.lang.annotation.ElementType.TYPE )
@Documented
@Import( DemoConfig.class )
@Configuration
public @interface EnableDemo 
    String param() default "";

DemoConfig 中仅仅只打印了一个初始化日志当作测试而已 ,同时DemoProperties也被当做配置注入进来,并且打印出来具体的配置数据


@Configuration
@EnableConfigurationProperties(DemoProperties.class)
public class DemoConfig 
    @Autowired
    private DemoProperties demoProperties;
    Logger                 logger = LoggerFactory.getLogger(getClass());

    @PostConstruct
    public void init() 
        logger.info("######DemoConfig init####### demoProperties is ", demoProperties.toString());
    


如何拿到@EnableDemo注解中参数的配置呢

这里针对DemoConfig做了一个优化,代码如下所示



@Configuration
@EnableConfigurationProperties(DemoProperties.class)
public class DemoConfig implements ImportAware, BeanClassLoaderAware 
    @Autowired
    private DemoProperties demoProperties;
    Logger                 logger = LoggerFactory.getLogger(getClass());
    private ClassLoader    classLoader;
    private String         param;

    @PostConstruct
    public void init() 
        logger.info("######DemoConfig init####### param is  demoProperties is ", param, demoProperties.toString());
    

    @Override
    public void setImportMetadata(AnnotationMetadata annotationMetadata) 
        Map<String, Object> enableAttrMap = annotationMetadata.getAnnotationAttributes(EnableDemo.class.getName());
        AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
        if (enableAttrs == null) 
            // search parent classes
            Class<?> currentClass = ClassUtils.resolveClassName(annotationMetadata.getClassName(), classLoader);
            for (Class<?> classToInspect = currentClass; classToInspect != null; classToInspect = classToInspect
                .getSuperclass()) 
                EnableDemo enableDemo = AnnotationUtils.findAnnotation(classToInspect, EnableDemo.class);
                if (enableDemo == null) 
                    continue;
                
                enableAttrMap = AnnotationUtils.getAnnotationAttributes(enableDemo);
                enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
            
        
        this.param = enableAttrs.getString("param");
    

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) 
        this.classLoader = classLoader;
    

上面流程大概是实现了ImportAware接口,也就是注解被解析完之后的一个回调,然后通过这个回调拿到具体的参数而已

大概流程基本都完成了,这样就能够完成一个简单的@EnableDemo配置

2.3 yaml自动提示

在spring boot中如果使用application.yaml进行项目配置,会产生一个自动提示,这个自动提示可以自己定义开发的

之前上面代码中有个DemoProperties,现在可以继续看看,首先是@ConfigurationProperties这个注解,通过prefix来配置前缀,假设我们配置的前缀是springboot.demo


@ConfigurationProperties(prefix = "springboot.demo")
public class DemoProperties 
    private String name;
    private String select;

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getSelect() 
        return select;
    

    public void setSelect(String select) 
        this.select = select;
    

    @Override
    public String toString() 
        return "DemoProperties" + "name='" + name + '\\'' + ", select='" + select + '\\'' + '';
    

如果想让上述的配置在application.yaml进行自动提示,需要进行两步,第一步是确保maven中有processor

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

第二步需要对idea
编辑器进行配置Preferences->Build, Execution, Deployment->Compile->Annotation Processors->Enable annonation processing
钩上这个选项,这样的话就会自动在target/classes/META-INF中生成spring-configuration-metadata.json文件
下面是效果图

总体代码在

http://git.oschina.net/wangkang_daydayup/SpringBoot-Learn/tree/master/springboot-11

扩展

spring.factories

简单的说一下spring.factories这个主要是提供了一个功能,就是自动配置,不需要使用@EnableXXX来开启,也就是说只要你用了springboot,并且依赖了一个jar包,这个jar包就会自动进行初始化
那么这个过程就是使用了spring.factories这个文件配置

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.start.config.AudoDemoConfig

下面的com.start.config.AudoDemoConfig就是自己定义的config,springboot启动的时候就会自动扫描,具体使用可以查看下面这个项目中的com.start.config.AudoDemoConfig
http://git.oschina.net/wangkang_daydayup/SpringBoot-Learn/tree/master/springboot-11

spring-configuration-metadata.json

如果仔细看target/classes/META-INF中,你就会发现有那么一个文件的存在spring-configuration-metadata.json,这个就是整个application.yaml提示的配置,他是自动生成的



  "hints": [],
  "groups": [
    
      "sourceType": "com.start.config.DemoProperties",
      "name": "springboot.demo",
      "type": "com.start.config.DemoProperties"
    
  ],
  "properties": [
    
      "sourceType": "com.start.config.DemoProperties",
      "name": "springboot.demo.name",
      "type": "java.lang.String"
    ,
    
      "sourceType": "com.start.config.DemoProperties",
      "name": "springboot.demo.select",
      "type": "java.lang.String"
    
  ]

具体的英文文档可以查看http://docs.spring.io/spring-boot/docs/current/reference/html/configuration-metadata.html#configuration-metadata-annotation-processor
这个json文件主要分为三个部分,首先是group,group代表一个类,比如DemoProperties,一个项目中存在多个group,而propertis代表是类里面的属性通过sourceType来确定是那一个类的
然后是hints,语意上来说就是提示

hints的使用

具体项目中的使用,可以通过在resources/META-INF 中放入spring-configuration-metadata.json文件,文件内容如下



  "hints": [
    
      "name": "springboot.demo.select",
      "values": [
        
          "value": "1",
          "description": "1的描述"
        ,
        
          "value": "2",
          "description": "2的描述"
        
      ]
    
  ],
  "groups": [
    
      "sourceType": "com.start.config.DemoProperties",
      "name": "springboot.demo",
      "type": "com.start.config.DemoProperties"
    
  ],
  "properties": [
    
      "sourceType": "com.start.config.DemoProperties",
      "name": "springboot.demo.name",
      "type": "java.lang.String"
    ,
    
      "sourceType": "com.start.config.DemoProperties",
      "name": "springboot.demo.select",
      "type": "java.lang.String"
    
  ]

效果图

『中级篇』docker之java容器运行外置springboot-jar(番外篇)(79)

...全部使用docker的方式感觉特别爽,我这里分享下,我部署springboot的富jar包。下载java的镜像dockerpulljava:openjdk-8springboot打包后的富jar放入指定的目录。执行命令创建容器内部路径/opt/pj/business.jar,容器路径/usr/business.jar。执行jarjava-... 查看详情

springboot学习路线大全之springboot与分布式保姆式教程

SpringBoot学习路线大全之SpringBoot与分布式【保姆式教程】值得一看 查看详情

springboot学习路线大全之springboot与分布式保姆式教程

SpringBoot学习路线大全之SpringBoot与分布式【保姆式教程】值得一看 查看详情

springboot初始教程之日志处理

SpringBoot初始教程之日志处理(二)1.介绍SpringBoot默认是采用logback进行日志处理、Logback是由log4j创始人设计的又一个开源日志组件。Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-classic和... 查看详情

springboot参考教程springboot配置使用之配置文件用法

4.1SpringBoot配置使用之配置文件用法 SpringBoot旨在简化配置,但依然需要进行少量配置来满足应用的特定需要。配置方式抛弃了XML文件的配置方式,主要使用配置文件和配置类来实现自定义配置,但依然可以使用XML文件的方式... 查看详情

springboot初始教程之项目结构(代码片段)

SpringBoot初始教程之项目结构1简介SpringBootmakesiteasytocreatestand-alone,production-gradeSpringbasedApplicationsthatyoucan“justrun”.WetakeanopinionatedviewoftheSpringplatformandthird-partylibrariessoyoucangetst 查看详情

springboot初始教程之项目结构(代码片段)

SpringBoot初始教程之项目结构1简介SpringBootmakesiteasytocreatestand-alone,production-gradeSpringbasedApplicationsthatyoucan“justrun”.WetakeanopinionatedviewoftheSpringplatformandthird-partylibrariessoyoucangetst 查看详情

springboot参考教程springboot配置使用之配置类用法

4.2.SpringBoot配置使用之配置类使用SpringBoot的大部分自动配置都可以满足应用要求,但如果想精确的控制应用,或者想覆盖自动配置,使用配置类是另一种很好的选择,强调一下,SpringBoot主要使用配置文件和配置类来做配置。1.&nb... 查看详情

springboot系列教程之事务传递属性

200202-SpringBoot系列教程之事务传递属性对于mysql而言,关于事务的主要知识点可能几种在隔离级别上;在Spring体系中,使用事务的时候,还有一个知识点事务的传递属性同样重要,本文将主要介绍7中传递属性的使用场景I.配置本... 查看详情

springboot初始教程之热部署(代码片段)

SpringBoot初始教程之热部署(五)1.介绍SpringBoot提供了一个maven插件来支持热部署spring-boot-devtools,仅仅是在开发环境中使用,如果已经打包了就无法使用。<dependencies><dependency><groupId>org.springframework.boot</groupId>& 查看详情

springboot初始教程之热部署(代码片段)

SpringBoot初始教程之热部署(五)1.介绍SpringBoot提供了一个maven插件来支持热部署spring-boot-devtools,仅仅是在开发环境中使用,如果已经打包了就无法使用。<dependencies><dependency><groupId>org.springframework.boot</groupId>& 查看详情

springboot初始教程之统一异常处理(代码片段)

SpringBoot初始教程之统一异常处理(三)1.介绍在日常开发中发生了异常,往往是需要通过一个统一的异常处理处理所有异常,来保证客户端能够收到友好的提示。SpringBoot在页面发生异常的时候会自动把请求转到/error,Spr... 查看详情

springboot初始教程之统一异常处理(代码片段)

SpringBoot初始教程之统一异常处理(三)1.介绍在日常开发中发生了异常,往往是需要通过一个统一的异常处理处理所有异常,来保证客户端能够收到友好的提示。SpringBoot在页面发生异常的时候会自动把请求转到/error,Spr... 查看详情

springboot初始教程之springboot-metrics监控(代码片段)

SpringBoot初始教程之SpringBoot-Metrics监控(十)1.介绍Metrics基本上是成熟公司里面必须做的一件事情,简单点来说就是对应用的监控,之前在一些技术不成熟的公司其实是不了解这种概念,因为业务跟技术是相关的当业务庞... 查看详情

springboot初始教程之springboot-metrics监控(代码片段)

SpringBoot初始教程之SpringBoot-Metrics监控(十)1.介绍Metrics基本上是成熟公司里面必须做的一件事情,简单点来说就是对应用的监控,之前在一些技术不成熟的公司其实是不了解这种概念,因为业务跟技术是相关的当业务庞... 查看详情

springboot初始教程之servletfilterlistener配置(代码片段)

SpringBoot初始教程之Servlet、Filter、Listener配置(七)1.介绍通过之前的文章来看,SpringBoot涵盖了很多配置,但是往往一些配置是采用原生的Servlet进行的,但是在SpringBoot中不需要配置web.xml的因为有可能打包之后是一个jar包... 查看详情

springboot初始教程之日志处理(代码片段)

SpringBoot初始教程之日志处理(二)1.介绍SpringBoot默认是采用logback进行日志处理、Logback是由log4j创始人设计的又一个开源日志组件。Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-class... 查看详情

springboot初始教程之日志处理(代码片段)

SpringBoot初始教程之日志处理(二)1.介绍SpringBoot默认是采用logback进行日志处理、Logback是由log4j创始人设计的又一个开源日志组件。Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-class... 查看详情