设为首页 加入收藏

TOP

Spring Boot 自动配置的 “魔法” 是如何实现的?(三)
2018-06-10 15:40:27 】 浏览:875
Tags:Spring Boot 自动 配置 魔法 如何 实现

quot;.equalsIgnoreCase(dbType); } }

我们已经尝试并实现了各种类型的条件判断,接下来,我们可以选择一种更为优雅的方式,就像@Profile一样,以注解的方式来完成条件判断。首先,我们需要定义一个注解类。

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(DatabaseTypeCondition.class)
public @interface DatabaseType {
	String value();
}

具体的条件判断逻辑在DatabaseTypeCondition类中,它会根据系统参数dbType来判断注册哪一个Bean。

public class DatabaseTypeCondition implements Condition {
	@Override
	public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
		Map<String, Object> attributes = metadata
											.getAnnotationAttributes(DatabaseType.class.getName());
		String type = (String) attributes.get("value");
		// 默认值为MySql
		String enabledDBType = System.getProperty("dbType", "MySql");
		return (enabledDBType != null && type != null && enabledDBType.equalsIgnoreCase(type));
	}
}

最后,在配置类应用该注解即可。

@Configuration
@ComponentScan
public class AppConfig {
	@Bean
	@DatabaseType("MySql")
	public UserDAO jdbcUserDAO() {
		return new JdbcUserDAO();
	}
	@Bean
	@DatabaseType("mongoDB")
	public UserDAO mongoUserDAO() {
		return new MongoUserDAO();
	}
}

AutoConfigure源码分析


通过了解@Conditional注解的机制其实已经能够猜到自动配置是如何实现的了,接下来我们通过源码来看看它是怎么做的。本文中讲解的源码基于Spring Boot 1.5.9版本(最新的正式版本)。

使用过Spring Boot的童鞋应该都很清楚,它会替我们生成一个入口类,其命名规格为ArtifactNameApplication,通过这个入口类,我们可以发现一些信息。

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

首先该类被@SpringBootApplication注解修饰,我们可以先从它开始分析,查看源码后可以发现它是一个包含许多注解的组合注解。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "exclude"
    )
    Class<?>[] exclude() default {};
    @AliasFor(
        annotation = EnableAutoConfiguration.class,
        attribute = "excludeName"
    )
    String[] excludeName() default {};
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};
    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};
}

该注解相当于同时声明了@Configuration、@EnableAutoConfiguration与@ComponentScan三个注解(如果我们想定制自定义的自动配置实现,声明这三个注解就足够了),而@EnableAutoConfiguration是我们的关注点,从它的名字可以看出来,它是用来开启自动配置的,源码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    Class<?>[] exclude() default {};
  
		
Spring Boot 自动配置的 “魔法” 是如何实现的?(三) https://www.cppentry.com/bencandy.php?fid=76&id=170268

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇linux 如何更改网卡 MAC 地址 下一篇JDK 源码阅读 : FileDescriptor