Spring Boot(04)——创建自己的自动配置
创建自己的自动配置
当你的应用需要以jar包的形式提供给其它应用使用时,可以考虑把它们封装为一个Spring Boot Starter。即该jar包是可以自动添加需要引用的依赖项,也能够对核心功能进行自动配置。自动配置的核心类是一个标注了@Configuration
的类,然后在自动配置类中可以定义相应的bean。比如下面的配置类中定义了一个HelloBean类型的bean。
@Configuration public class HelloAutoConfiguration { @Bean public HelloBean helloBean() { return new HelloBean(); } }
然后需要在Classpath下的META-INF/spring.factories
中以org.springframework.boot.autoconfigure.EnableAutoConfiguration
为Key,以对应的自动配置类为Value进行配置,如果有多个自动配置类,多个自动配置类之间可以以英文逗号分隔。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.elim.autoconfigure.HelloAutoConfiguration
Spring Boot在启动时将读取Classpath下META-INF/spring.factories
中Key为org.springframework.boot.autoconfigure.EnableAutoConfiguration
的配置类,将它们进行实例化。所以经过上述配置后,系统启动后将自动创建HelloBean类型的bean。
自动配置类通常不会像上面那样直接进行定义,而是会添加一些附加条件,比如在Classpath中拥有某些Class才生效,或者需要bean容器中不存在指定bean时才生效等等。Spring Boot为它们提供了一系列的@ConditionalXXX
,常用的如下:
- ConditionalOnClass :用于指定在Classpath下拥有某些Class时才生效
- ConditionalOnMissingClass :用于指定在Classpath下不存在某些Class时才生效
- ConditionalOnBean :用于指定在bean容器中存在某些bean时生效
- ConditionalOnMissingBean :用于指定在bean容器中不存在某些bean时生效
- ConditionalOnWebApplication :用于指定当应用是Web应用时生效
- ConditionalOnNotWebApplication :用于指定当应用是非Web应用时生效
- ConditionalOnProperty :用于指定当配置了某些特定的参数时生效
- ConditionalOnExpression :用于根据SpEl表达式控制是否生效
- ConditionalOnSingleCandidate :用于指定当bean容器中只存在唯一的指定类型的bean时才生效;当bean容器中存在多个指定类型的bean,但是使用
@Primary
指定了主候选者也是可以匹配的,即也是生效的
更多可用的Conditional注解可以参考API文档的
org.springframework.boot.autoconfigure.condition
包。
下面的代码中指定了当Classpath下存在Hello.class,且bean容器中不存在HelloBean类型的bean时下面的配置类将生效。
@Configuration @ConditionalOnClass(Hello.class) @ConditionalOnMissingBean(HelloBean.class) public class HelloAutoConfiguration { @Bean public HelloBean helloBean() { return new HelloBean(); } }
这些条件配置注解也是可以添加到bean上的。比如下面代码中指定了当Environment中存在Key为autoconfigure.hello.enabled
属性且其值为true时将创建HelloBean类型的bean,或者当Environment中不存在Key为autoconfigure.hello.enabled
属性时也将创建HelloBean类型的bean(由matchIfMissing控制)。所以针对下面的配置,默认情况下是会创建HelloBean类型的bean的,如果不期望创建该类型的bean,可以在application.properties文件中指定autoconfigure.hello.enabled=false
。
@Configuration @ConditionalOnClass(Hello.class) @ConditionalOnMissingBean(HelloBean.class) public class HelloAutoConfiguration { @Bean @ConditionalOnProperty(prefix = "autoconfigure.hello", name = "enabled", havingValue = "true", matchIfMissing = true) public HelloBean helloBean() { return new HelloBean(); } }
当使用@ConditionalOnProperty时如果对应的值的可选值是true/false,可以不指定havingValue属性,此时只要值不为false,都会认为是true。
绑定参数
通常自定义的Starter会需要依靠外部配置的属性进行一些自动配置。此时可以使用@ConfigurationProperties
标注在用来接收属性的Class上,它可以指定一个前缀,然后将在application.properties中寻找指定前缀和字段名称组合起来的属性进行绑定。比如下面的属性类中的name属性将绑定application.properties中定义的autoconfigure.hello.name
属性的值。
@Data @ConfigurationProperties("autoconfigure.hello") public class HelloProperties { private String name; private String message; }
@ConfigurationProperties
标注的Class需要通过在配置类上使用@EnableConfigurationProperties
进行启用。@EnableConfigurationProperties
指定的配置类会自动注册为Spring bean容器中的一个bean,然后可以在配置类中自动注入对应的属性类。比如下面的代码中在HelloAutoConfiguration类上通过@EnableConfigurationProperties(HelloProperties.class)
指定了启用HelloProperties这个属性配置类,然后把它定义为HelloAutoConfiguration类中的一个属性,并标注为自动注入,然后在定义HelloBean类型的bean时从HelloProperties中获取属性值进行配置。
@Configuration @ConditionalOnClass(Hello.class) @ConditionalOnMissingBean(HelloBean.class) @EnableConfigurationProperties(HelloProperties.class) public class HelloAutoConfiguration { @Autowired private HelloProperties helloProperties; @Bean @ConditionalOnProperty(prefix = "autoconfigure.hello", name = "enabled", matchIfMissing = true) public HelloBean helloBean() { HelloBean helloBean = new HelloBean(); helloBean.setName(helloProperties.getName()); return helloBean; } }
上面的代码中定义HelloBean时从HelloProperties中获取name属性赋值给了HelloBean对象的name属性。这样的需求其实可以直接通过@ConfigurationProperties
给HelloBean的name属性赋值,而不必添加多余的HelloProperties类。把@ConfigurationProperties
定义在HelloBean定义的方法上可以拥有相同的效果,比如下面这样。
@Configuration @ConditionalOnClass(Hello.class) @ConditionalOnMissingBean(HelloBean.class) public class HelloAutoConfiguration { @Bean @ConditionalOnProperty(prefix = "autoconfigure.hello", name = "enabled", matchIfMissing = true) @ConfigurationProperties("autoconfigure.hello") public HelloBean helloBean() { return new HelloBean(); } }
使用
@ConfigurationProperties
定义属性配置类时最好定义的前缀不要以spring开头,以免跟未来Spring官方提供的属性配置类存在冲突。自定义的Starter在命名时不要命名为
spring-boot-starter-xxx
,可以命名为xxx-spring-boot-starter
。spring-boot-starter-xxx
留给官方使用。
参考文档
(注:本文基于Spring Boot 2.0.3所写)

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Spring Boot(03)——自动配置
Spring Boot 自动配置 Spring Boot的自动配置功能会根据Classpath中的Class为我们自动创建相应的bean。比如当classpath下存在MongoClient.class和MongoTemplate.class时就会进行Spring Data MongoDB的配置。这是通过MongoDataAutoConfiguration类配置的。下面是MongoDataAutoConfiguration类的定义,可以看到上面使用了@Configuration注解定义,且通过@ConditionalOnClass注解指定了只有在存在MongoClient.class和MongoTemplate.class时才会生效。@EnableConfigurationProperties指定了可以使用的配置属性类,Spring Boot会自动生成对应类型的bean,以供我们在自动配置类中进行依赖注入。@AutoConfigureAfter定义了该自动配置类生效的位置,下面代码指定了将在MongoAutoConfiguration配置类之后生效。 @Configuration @C...
- 下一篇
Scala Try 与错误处理
一.概述 当你在尝试一门新的语言时,可能不会过于关注程序出错的问题, 但当真的去创造可用的代码时,就不能再忽视代码中的可能产生的错误和异常了。 鉴于各种各样的原因,人们往往低估了语言对错误处理支持程度的重要性。 事实会表明,Scala 能够很优雅的处理此类问题, 这一部分,我会介绍 Scala 基于 Try 的错误处理机制,以及这背后的原因。 我将使用一个在 Scala 2.10 新引入的特性,该特性向 2.9.3 兼容, 因此,请确保你的 Scala 版本不低于 2.9.3。 二.异常抛出与捕获 2.1 其他语言的错误处理机制 在介绍 Scala 错误处理的惯用法之前,我们先看看其他语言(如,Java,Ruby)的错误处理机制。 和这些语言类似,Scala 也允许你抛出异常: case class Customer(age: Int) class Cigarettes case class UnderAgeException(message: String) extends Exception(message) def buyCigarettes(customer: Customer...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS6,CentOS7官方镜像安装Oracle11G
- Red5直播服务器,属于Java语言的直播服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- CentOS关闭SELinux安全模块