@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class);
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
この@Importで何をするのですか?えー......ここでは単に、次の理解の中で自分自身に行くことができると言います。Importアノテーションは、Spring IOCにクラスをインポートするために使用され、通常の@Componentアノテーションは、クラスBeanとして宣言されます似ています。
さて、ここでEnableAutoConfiguration.classこのクラスの初期化にこの時点で行くことを知り、その後、内部を見るためにこのクラスに入ってみましょう:
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
private static final AutoConfigurationImportSelector.AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationImportSelector.AutoConfigurationEntry();
private static final String[] NO_IMPORTS = new String[0];
private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);
private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";
private ConfigurableListableBeanFactory beanFactory;
private Environment environment;
private ClassLoader beanClassLoader;
private ResourceLoader resourceLoader;
public AutoConfigurationImportSelector() {
}
/**
* IOC コンテナーに注入するクラス名の配列を返す。
*/
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
/**
* それは、以下のメソッドを呼び出すことである
*/
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
/**
* このステップでは、META-INF/springパスにあるすべてのクラスをスキャンする。.factoriesファイルから、コンフィギュレーション・クラスの内部で
*/
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
}
}
このクラスはかなり長いので、このクラスの実行について簡単に説明します:
- AutoConfigurationImportSelector クラスは ImportSelector インターフェイスを実装し、その selectImports() メソッドをオーバーライドします。
- オーバーライドされた selectImports() メソッドは、内部の getAutoConfigurationEntry() メソッドを呼び出します。このメソッドは、クラスパス内のすべての META-INF/spring.facts ファイルをスキャンし、そこから設定クラスを取得します。
実際には、ここを参照してください、おそらく理解することができます。In fact, the development of the introduction of those starter packages will almost always contain META-INF/spring.factories such a file, like the commonly used mybatis-spring-boot-starter, it is inside the spring.factories configuration file is this:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
そして、MybatisAutoConfigurationクラスをIOCにロードし、同時にこのクラスは他のBeanを宣言します。
@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setVfs(SpringBootVFS.class);
if (StringUtils.hasText(this.properties.getConfigLocation())) {
factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
}
this.applyConfiguration(factory);
if (this.properties.getConfigurationProperties() != null) {
factory.setConfigurationProperties(this.properties.getConfigurationProperties());
}
ConditionalOnMissingBeanアノテーションは、Beanコンテナにクラスが存在しない場合に、そのクラスをBeanコンテナに初期化することを意味します:
- ConditionalOnWebApplication: ウェブアプリケーションでのみ有効です。
- ConditionalOnClass:指定されたクラスが存在しないと有効になりません。
- @ConditionalOnProperty: 指定されたプロパティがメイン構成ファイルに存在する場合に有効になります。
この一連のConditionalアノテーションによって、スターターの他のビーンズはIOCにインスタンス化され、メインプロジェクトで直接参照できるようになりました。
最後にまとめると、SpringBootプロジェクトが起動すると、各クラスパスの下にあるMETA-INF/spring.factsファイルをスキャンし、このファイルがAutoConfigurationクラスに対応し、このクラスをインスタンス化すると同時に、@ConditionalOnアノテーションと@Beanアノテーションを通じて、このAutoConfigurationクラスがIOCコンテナに初期化されます。AutoConfiguration クラスがインスタンス化されると同時に、一連の機能クラスが @ConditionalOn アノテーションと @Bean アノテーションを通じて IOC コンテナに初期化されます。つまり、maven pom を通じて導入が完了し、自動アセンブルの機能が完成します。





