Spring Boot是Spring旗下浩瀚的子项目之一,其理念是约定优于设置,它通过实现了自动设置(大大都用户平时习惯配置的设置作为默认设置)的成果来为用户快速构建出尺度化的应用。Spring Boot的特点可以概述为如下几点:
有关Spring Boot的利用要领就不做多先容了,如有乐趣请自行阅读官方文档Spring Boot或其他文章。
如今微处事的观念愈来愈热,转型或实验微处事的团队也在如日渐增,而对付技能选型,Spring Cloud是一个较量好的选择,它提供了一站式的漫衍式系统办理方案,包括了很多构建漫衍式系统与微处事需要用到的组件,譬喻处事管理、API网关、设置中心、动静总线以及容错打点等模块。可以说,Spring Cloud”全家桶”极其适合方才打仗微处事的团队。好像有点跑题了,不外说了这么多,我想要强调的是,Spring Cloud中的每个组件都是基于Spring Boot构建的,而领略了Spring Boot的自动设置的道理,显然也是有长处的。
Spring Boot的自动设置看起来神奇,其实道理很是简朴,背后全依赖于@Conditional注解来实现的。
本文作者为SylvanasSun(sylvanas.sun@gmail.com),首发于SylvanasSun’s Blog。
原文链接:https://sylvanassun.github.io/2018/01/08/2018-01-08-spring_boot_auto_configure/
(转载请务必保存本段声明,而且保存超链接。)
什么是@Conditional?
@Conditional是由Spring 4提供的一个新特性,用于按照特定条件来节制Bean的建设行为。而在我们开拓基于Spring的应用的时候,不免会需要按照条件来注册Bean。
譬喻,你想要按照差异的运行情况,来让Spring注册对应情况的数据源Bean,对付这种简朴的环境,完全可以利用@Profile注解实现,就像下面代码所示:
@Configuration public class AppConfig { @Bean @Profile("DEV") public DataSource devDataSource() { ... } @Bean @Profile("PROD") public DataSource prodDataSource() { ... } }
剩下只需要配置对应的Profile属性即可,配置要领有如下三种:
context.getEnvironment().setActiveProfiles("PROD")
来配置Profile属性。spring.profiles.active
参数来配置情况(Spring Boot中可以直接在application.properties
设置文件中配置该属性)。<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>spring.profiles.active</param-name> <param-value>PROD</param-value> </init-param> </servlet>
但这种要领只范围于简朴的环境,并且通过源码我们可以发明@Profile自身也利用了@Conditional注解。
package org.springframework.context.annotation; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Conditional({ProfileCondition.class}) // 组合了Conditional注解 public @interface Profile { String[] value(); } package org.springframework.context.annotation; class ProfileCondition implements Condition { ProfileCondition() { } // 通过提取出@Profile注解中的value值来与profiles设置信息举办匹配 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { if(context.getEnvironment() != null) { MultiValueMap attrs = metadata.getAllAnnotationAttributes(Profile.class.getName()); if(attrs != null) { Iterator var4 = ((List)attrs.get("value")).iterator(); Object value; do { if(!var4.hasNext()) { return false; } value = var4.next(); } while(!context.getEnvironment().acceptsProfiles((String[])((String[])value))); return true; } } return true; } }