1. 程式人生 > >Spring 多個Conditional -> Bean建立

Spring 多個Conditional -> Bean建立

    @Bean
    @ConditionalOnBean(DataSource.class) // 1
    @ConditionalOnProperty("xxx") //2
    public String hello(){
        System.out.println(">>>>>>>>>>>>>>>> init..... Hello world");
        return "Hello World";
    }

考慮一個問題?
在這個裡面,滿足什麼條件才會建立hello這個Bean

  • 猜想1:滿足條件1或條件2
  • 猜想2:滿足條件1和條件2
  • 猜想3:無需滿足任何條件

顯然 猜想3 是錯誤的

… 十秒鐘之後

經過試驗,

猜想2正確.

那麼是為什麼呢?

首先這個在@Configuration裡面,那麼入口應該是,解析Configuration這個類ConfigurationClassPostProcessor

然後它是藉助ConfigurationClassBeanDefinitionReader這個類解析Configuration

然後在這個類的loadBeanDefinitionsForBeanMethod()方法中,這麼一個判斷條件

        // Do we need to mark the bean as skipped by its condition?
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { configClass.skippedBeanMethods.add(methodName); return; }

沒錯,看到了我們的Condition

然後點選進去 可以進入到ConditionEvalutor這個類裡面

    /**
     * Determine if an item should be skipped based on {@code @Conditional
} annotations. * @param metadata the meta data * @param phase the phase of the call * @return if the item should be skipped */
public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) { // 如果沒有註解或者註解中沒有Conditional這種註解 if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) { return false; } if (phase == null) { if (metadata instanceof AnnotationMetadata && ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) { return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION); } return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN); } List<Condition> conditions = new ArrayList<Condition>(); // 獲取所有的condition for (String[] conditionClasses : getConditionClasses(metadata)) { for (String conditionClass : conditionClasses) { Condition condition = getCondition(conditionClass, this.context.getClassLoader()); conditions.add(condition); } } // 排序,需實現Order介面 AnnotationAwareOrderComparator.sort(conditions); for (Condition condition : conditions) { ConfigurationPhase requiredPhase = null; if (condition instanceof ConfigurationCondition) { requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase(); } if (requiredPhase == null || requiredPhase == phase) { // 只要有一個不符合,就跳過建立 if (!condition.matches(this.context, metadata)) { return true; } } } return false; }

所以可以看到,需要符合所有的Condition才可以成功建立Bean