乐趣区

关于springboot:AutoConfigureAfter和AutoConfigureBefore排序失效了

@AutoConfigureAfter 和 @AutoConfigureBefore 排序生效了?

注释

聊聊 SpringBoot Bean 加载和 主动配置的程序问题。

理论误区

来看看理论开发中存在的问题。咱们想要的后果 A –>B–>C,上面写法是最常见的谬误。

@Configuration
public class ConfigurationA {ConfigurationA(){System.out.println("CofigurationA  曾经被初始化!");
    }
}


@Configuration
@AutoConfigureAfter(ConfigurationA.class)
public class ConfigurationB {ConfigurationB(){System.out.println("ConfigurationB  曾经被初始化!");
    }
}


@Configuration
@AutoConfigureAfter(ConfigurationB.class)
public class ConfigurationC {ConfigurationC(){System.out.println("CofigurationC  曾经被初始化!");
    }
}

来来来执行一把。。。。

执行后果:CofigurationA   曾经被初始化!ConfigurationB  曾经被初始化!CofigurationC   曾经被初始化!

WTF!!!!!!!! 不是说有问题吗?

别急!!调整下代码,想要的后果是 C –>B–>A, 来将代码调整下:

@Configuration
@AutoConfigureAfter(ConfigurationB.class)
public class ConfigurationA {ConfigurationA(){System.out.println("CofigurationA  曾经被初始化!");
    }
}


@Configuration
@AutoConfigureAfter(ConfigurationC.class)
public class ConfigurationB {ConfigurationB(){System.out.println("ConfigurationB  曾经被初始化!");
    }
}


@Configuration
public class ConfigurationC {ConfigurationC(){System.out.println("CofigurationC  曾经被初始化!");
    }
}

来来开席开席!!!!

执行后果:CofigurationA   曾经被初始化!ConfigurationB  曾经被初始化!CofigurationC   曾经被初始化!

从下面的后果是能够看出 @AutoConfigureAfter 并没有什么卵用。第一次可能失去正确后果是老天保佑。。。。。

所以来看看源码:@AutoConfigureAfter 归纳来说得益于 SpringBoot 主动配置 (@EnableAutoConfiguration);@EnableAutoConfiguration 通过 @Import 将 EnableAutoConfigurationImportSelector 引入
这边次要看下 EnableAutoConfigurationImportSelector–>selectImports()办法

    public String[] selectImports(AnnotationMetadata metadata) {if (!isEnabled(metadata)) {return NO_IMPORTS;}
        try {AnnotationAttributes attributes = getAttributes(metadata);
            // 加载 META-INF 下 spring.factories 配置类
            List<String> configurations = getCandidateConfigurations(metadata,
                    attributes);
            configurations = removeDuplicates(configurations);
            Set<String> exclusions = getExclusions(metadata, attributes);
            configurations.removeAll(exclusions);
            // 将配置类进行排序
            configurations = sort(configurations);
            recordWithConditionEvaluationReport(configurations, exclusions);
            return configurations.toArray(new String[configurations.size()]);
        }
        catch (IOException ex) {throw new IllegalStateException(ex);
        }
    }
    
    
    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
                AnnotationAttributes attributes) {
            List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
            Assert.notEmpty(configurations,
                    "No auto configuration classes found in META-INF/spring.factories. If you"
                            + "are using a custom packaging, make sure that file is correct.");
            return configurations;
        }

看到这里法外狂徒 “ 张三 ” 默默的在 META-INF 下 spring.factories 加上了 …….

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.*******.Demo.ConfigurationA,\
com.*******.Demo.ConfigurationB,\
com.*******.Demo.ConfigurationC

张三:就这,就这 ……?张三启动了核按钮:

执行后果:CofigurationA   曾经被初始化!ConfigurationB  曾经被初始化!CofigurationC   曾经被初始化!

退出移动版