设为首页 加入收藏

TOP

Spring Boot 自动配置的 “魔法” 是如何实现的?(二)
2018-06-10 15:40:27 】 浏览:932
Tags:Spring Boot 自动 配置 魔法 如何 实现
ing容器中是否已经注册了某种类型的Bean(如未注册,我们可以让其自动注册到容器中,上一条同理)。
  • 一个文件是否在特定的位置上。
  • 一个特定的系统属性是否存在。
  • 在Spring的配置文件中是否设置了某个特定的值。
  • 举个栗子,假设我们有两个基于不同数据库实现的DAO,它们全都实现了UserDao,其中JdbcUserDAO与MySql进行连接,MongoUserDAO与MongoDB进行连接。现在,我们有了一个需求,需要根据命令行传入的系统参数来注册对应的UserDao,就像java -jar app.jar -DdbType=MySQL会注册JdbcUserDao,而java -jar app.jar -DdbType=MongoDB则会注册MongoUserDao。使用@Conditional可以很轻松地实现这个功能,仅仅需要在你自定义的条件类中去实现Condition接口,让我们来看下面的代码。(以下案例来自:https://dzone.com/articles/how-springboot-autoconfiguration-magic-works)

    public interface UserDAO {
    	....
    }
    public class JdbcUserDAO implements UserDAO {
    	....
    }
    public class MongoUserDAO implements UserDAO {
    	....
    }
    public class MySQLDatabaseTypeCondition implements Condition {
    	@Override
    	public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
     		String enabledDBType = System.getProperty("dbType"); // 获得系统参数 dbType
     		// 如果该值等于MySql,则条件成立
     		return (enabledDBType != null && enabledDBType.equalsIgnoreCase("MySql"));
     	}
    }
    // 与上述逻辑一致
    public class MongoDBDatabaseTypeCondition implements Condition {
    	@Override
    	public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
     		String enabledDBType = System.getProperty("dbType");
     		return (enabledDBType != null && enabledDBType.equalsIgnoreCase("MongoDB"));
     	}
    }
    // 根据条件来注册不同的Bean
    @Configuration
    public class AppConfig {
    	@Bean
    	@Conditional(MySQLDatabaseTypeCondition.class)
    	public UserDAO jdbcUserDAO() {
    		return new JdbcUserDAO();
    	}
    	
    	@Bean
    	@Conditional(MongoDBDatabaseTypeCondition.class)
    	public UserDAO mongoUserDAO() {
    		return new MongoUserDAO();
    	}
    }

    现在,我们又有了一个新需求,我们想要根据当前工程的类路径中是否存在MongoDB的驱动类来确认是否注册MongoUserDAO。为了实现这个需求,可以创建检查MongoDB驱动是否存在的两个条件类。

    public class MongoDriverPresentsCondition implements Condition {
    	@Override
    	public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
    		try {
    			Class.forName("com.mongodb.Server");
    			return true;
    		} catch (ClassNotFoundException e) {
    			return false;
    		}
    	}
    }
    public class MongoDriverNotPresentsCondition implements Condition {
    	@Override
    	public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
    		try {
    			Class.forName("com.mongodb.Server");
    			return false;
    		} catch (ClassNotFoundException e) {
    			return true;
    		}
    	}
    }

    假如,你想要在UserDAO没有被注册的情况下去注册一个UserDAOBean,那么我们可以定义一个条件类来检查某个类是否在容器中已被注册。

    public class UserDAOBeanNotPresentsCondition implements Condition {
    	@Override
    	public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
    		UserDAO userDAO = conditionContext.getBeanFactory().getBean(UserDAO.class);
    		return (userDAO == null);
    	}
    }

    如果你想根据配置文件中的某项属性来决定是否注册MongoDAO,例如app.dbType是否等于MongoDB,我们可以实现以下的条件类。

    public class MongoDbTypePropertyCondition implements Condition {
    	@Override
    	public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
    		String dbType = conditionContext.getEnvironment().getProperty("app.dbType");
    		return "MONGO&
    首页 上一页 1 2 3 4 5 6 7 下一页 尾页 2/7/7
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇linux 如何更改网卡 MAC 地址 下一篇JDK 源码阅读 : FileDescriptor

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目