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;
}
}