SpringBoot中级教程之SpringBoot自定义配置(十一)
2017-07-18 16:14
881 查看
SpringBoot中级教程之SpringBoot自定义配置(十一)
前言首先力推下我的开源项目
http://git.oschina.net/wangkang_daydayup/swagger-doc 这是一个完全利用spring boot开发的项目,拯救了springfox-swagger污染代码的问题,完全利用java-doc来实现,学习成本几乎是01.介绍
在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进行项目配置,会产生一个自动提示,这个自动提示可以自己定义开发的
![](http://git.oschina.net/wangkang_daydayup/SpringBoot-Learn/raw/master/springboot-11/image/enableconfig.png)
之前上面代码中有个
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/raw/master/springboot-11/image/enableconfig1.png)
总体代码在
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" } ] }
效果图
![](http://git.oschina.net/wangkang_daydayup/SpringBoot-Learn/raw/master/springboot-11/image/enableconfig2.png)
相关文章推荐
- spring boot学习教程(5):spring boot hibernate 配置
- Spring Boot教程(十一)Spring Boot Actuator监控端点小结(1)
- SpringBoot如何导入自定义配置的yml文件
- spring-boot application.properties配置文件和自定义配置文件
- 企业分布式微服务云SpringCloud SpringBoot mybatis (十九)Spring Boot 自定义配置文件
- spring boot使用自定义配置的线程池执行Async异步任务
- SpringBoot配置自定义线程池的数据源
- spring-boot @Async 的使用、自定义Executor的配置方法
- SpringBoot之配置文件及自定义参数
- SpringBoot如何导入自定义配置的yml文件
- spring-boot @Async 的使用、自定义Executor的配置方法
- spring boot之spring mvc常用配置--自定义HtppMessageConverter(9)
- Spring Boot参考教程(四)Spring Boot配置使用之配置文件用法
- spring-boot 线程池 @Async 的使用、自定义Executor的配置方法
- Spring Boot教程(一)注解配置与EhCache使用
- springboot 自定义yml 配置文件
- SpringBoot如何导入自定义配置的yml文件
- SpringCloud SpringBoot mybatis 分布式微服务(二十)Spring Boot 自定义配置文件
- Spring Boot系列教程四:配置文件详解properties
- Spring Boot系列教程四:配置文件详解properties