不学无数——SpringBoot入门Ⅶ

SpringBoot

1.创建自己的Auto-configuration

无论是在公司中你想开发自己的一套框架,定制一些东西,或者是在开源网站中分享自己做的一些东西。你可能想要开发属于自己的Auto-configuration。Auto-configuration的类能够捆绑到外部的jar包中,并且被SpringBoot进行使用。例如我们经常使用的@Autowire注解会自动的注入一个实例到Spring的容器中,这时我们被注入进来的类必须有个注解进行标注,例如:@Service、@Controller等等。但是对于在jar包中的类的话,考虑的需要多一些,例如需要考虑在注入时我会依赖到谁,谁先进行注入等等。

Auto-configuration通常是和starter联系起来的,一个官网提供的小例子展示了如何一步一步创建属于自己的starter

1.1 理解Auto-configured类

在底层代码中,Auto-configured是被@Configuration注解的类实现的。另外@Conditional注解被用来限制什么时候Auto-configured应该被应用。通常来说,Auto-configured的类使用@ConditionalOnClass@ConditionalOnMissingBean这两个注解,这是为了确保 auto-configuration 只在一些相关的类生效以后才会加载@Configuration类。

你也可以通过浏览SpringBoot-autoConfigure由Spring提供的@Configuration类。

1.2 Auto-configuration的目录结构

SpringBoot会检查所有jar包中的META-INF/spring.factories文件,在这个文件中应该列出了key是EnableAutoConfigurationvalue是想要配置的类,例如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

当然也可以使用@AutoConfigureAfter@AutoConfigureBefore两个注解进行标识想要哪个类进行先加载。例如想要提供一个特定的web配置,那么你的类应该在WebMvcAutoConfiguration之后加载。

如何想要auto-configurations的类进行顺序的加载,那么可以使用@AutoConfigureOrder注解进行排序。

Auto-configurations仅仅能够被这种方式进行加载,实际上,他们不会被包扫描进行加载。

1.3 Condition注解

SpringBoot利用@Condition注解来确定是不是要创建Bean实例

在所开发的对外封装jar包中可能会使用一个或者多个的@Condition注解在自动配置的类中。@ConditionalOnMissingBean注解会覆盖掉你的默认配置。

SpringBoot包括许多的@Conditional的注解,你能够重复使用它在类中或者单独的@Bean方法上。这些注解包括

  • Class Conditions
  • Bean Conditions
  • Property Conditions
  • Resource Conditions
  • Web Application Conditions

1.3.1 Class Conditions

  • @ConditionalOnClass: 某个class位于类路径上,才会实例化一个Bean。该注解的参数对应的类必须存在,否则不解析该注解修饰的配置类。这个很有用的,比如不同的jar包之间有依赖,如果依赖的类不存在的话,那么就会直接跳过,不会报错。
  • @ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean,可以给该注解传入参数例如@ConditionOnMissingBean(name = "example"),这个表示如果name为“example”的bean存在,这该注解修饰的代码块不执行

1.3.2 Bean Conditions

  • @ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean
  • @ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean

举例如下:

@Configuration
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() { ... }

}

1.3.3 Property Conditions

  • @ConditionalOnProperty:这个注解能够控制某个configuration是否生效。具体操作是通过其两个属性name以及havingValue来实现的,其中name用来从application.properties中读取某个属性值,如果该值为空,则返回false;如果值不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true;否则返回false。如果返回值为false,则该configuration不生效;为true则生效。

1.3.4 Resource Conditions

  • @ConditionalOnResource注解允许只有在特定资源出现时配置才会生效。资源可以使用常见的Spring约定命名,例如file:/home/user/test.dat。

1.3.5 Web Application Conditions

  • @ConditionalOnWebApplication和@ConditionalOnNotWebApplication两个注解会根据应用是否为一个Web应用而使配置生效。

2. 一个自动配置的小例子

2.1 创建一个接受配置属性的类

如果对于如何用java实体类进行接受配置文件的属性不明白的,可以参考我的文章不学无数——SpringBoot入门Ⅲ,里面有详细讲解。


@ConfigurationProperties("acme")
@Validated
public class AcmeProperties {
    private boolean enabled;
    @NotNull(message = "不能weikong ")
    private String remoteAddress;

    public boolean isEnabled() { return enabled; }

    public void setEnabled(boolean enabled) { this.enabled=enabled; }

    public String getRemoteAddress() { return remoteAddress; }

    public void setRemoteAddress(String remoteAddress) { this.remoteAddress=remoteAddress; }

}

2.2 创建配置属性的类

这里只是简单的举个配置属性的例子: 例如在这里可以进行配置数据库的事务。然后在动态创建数据源的时候可以判断这个类是否创建然后创建数据源。

即这个类是一个作为判断依据的类

public class AcmeService {
    private String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "AcmeService{" +
                "msg='" + msg + '\'' +
                '}';
    }
}

2.3 创建自动配置的类

@ConditionalOnClass该注解在之前已经讲过,这里的意思就是AcmeService类在路径中已经存在以后才会解析配置类。@ConditionalOnMissingBean方法上的注解我们上面也解释过了,在这的意思就是在容器中没有AcmeService对象时才会实例化此Bean。


@Configuration
@ConditionalOnClass(AcmeService.class)
@EnableConfigurationProperties(AcmeProperties.class)
public class AcmeAutoConfiguration {

    private final AcmeProperties acmeProperties;

    public AcmeAutoConfiguration(AcmeProperties acmeProperties) {
        this.acmeProperties = acmeProperties;
    }

    @Bean
    @ConditionalOnMissingBean(AcmeService.class)
    public AcmeService getAcmeService(){
        AcmeService acmeService=new AcmeService();
        acmeService.setMsg(acmeProperties.toString());
        return acmeService;
    }
}

2.4 注册配置

resources-META-INF文件夹下创建spring.factories文件,里面写入自动配置类的路径

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.FirstSpringBoot.Configuration.AcmeAutoConfiguration

2.5 开始使用

因为我们创建的自动配置是要供别人使用的,只对外提供配置的属性值,所以我们将我们写的自动配置的一系列类进行打jar包,另一个项目引用过后只需要在配置文件中配置我们对外提供的配置属性进行配置以后就可以使用我们自动配置类提供的功能了。这也正符合了SpringBoot的开箱即用的观点。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,869评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,716评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,223评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,047评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,089评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,839评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,516评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,410评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,920评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,052评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,179评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,868评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,522评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,070评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,186评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,487评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,162评论 2 356

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,830评论 6 342
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,673评论 18 139
  • 1.1 Spring IoC容器和bean简介 本章介绍了Spring Framework实现的控制反转(IoC)...
    起名真是难阅读 2,584评论 0 8
  • 1.1 spring IoC容器和beans的简介 Spring 框架的最核心基础的功能是IoC(控制反转)容器,...
    simoscode阅读 6,719评论 2 22
  • 凡选择必有歧视,凡竞争必有成本,凡政策必遭遇对策,凡争夺必有妥协。
    Adapa阅读 211评论 0 1