设为首页 加入收藏

TOP

Spring Boot 自动配置的 “魔法” 是如何实现的?(二)
2018-06-10 15:40:27 】 浏览:704
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
    @C
    		    

    onfiguration 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

    评论

    帐  号: 密码: (新用户注册)
    验 证 码:
    表  情:
    内  容:

    array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(217) }