Spring Boot実現原理
最も一般的なSprigBootアプリケーション起動クラス
この注釈に入ると、@Spring Bootapolicationはアンノテーションを組み合わせています.その中で一番重要なannotationは@Spring BootConfigrationで、@EnbaleAutoConfigrationと@ComponentScanです.
@ComponentScancanの注釈が完了したのは自動スキャンの機能で、Spring XML設定ファイルの中のに相当します.enclude Filters、include Filtersなどの属性を使ってスキャンするパケットを指定したり、排除したりすることができます.スキャンの条件もあります.最終的にこれらのbean定義を容器にロードする.
@Enbale AutoConfigrationは、Spring Bootの構成をこのように簡略化できるようにするためのキー注釈であり、Spring-Bootは、アプリケーションによって宣言されたjarパケット依存性に基づいてSpringフレームを自動的に配置する.たとえば
@Enbale AutoConfigration
メイン起動タイプのmain関数では、SpringAppleication.run(DemoApple.class,args)を呼び出して、2ステップに分けて実行します.第1ステップはSprigAplicationオブジェクトを作成し、第2ステップはrun方法を実行します.
第一歩、SpringAppleオブジェクトの作成
このステップの主な機能はSprigAplicationオブジェクトを初期化し、クラスパスの下からMETA-INF/spring.factores配置のすべてのApplizerとApplizerを見つけて保存して、最後にmainメソッドの主な構成クラスを見つけます.
run方法の重要なポイントは、IOC容器context=createApple plication Contect();最後に起動したIOC容器に戻ります.途中でrefreshContent()を呼び出し、最後にspring容器のrefreshに呼び出した場合、
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
springbootアプリケーションは、@Spring BootAlicationの注釈を設定するだけで、自動的に起動することができます.なぜですか?この注釈に入ると、@Spring Bootapolicationはアンノテーションを組み合わせています.その中で一番重要なannotationは@Spring BootConfigrationで、@EnbaleAutoConfigrationと@ComponentScanです.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {}
@Spring BootConfigrationは本質的には@Configrationです.スタートクラスに@Spring BootCofigrationと表示されていますが、それ自体もIOC容器の配置類です.@ComponentScancanの注釈が完了したのは自動スキャンの機能で、Spring XML設定ファイルの中のに相当します.enclude Filters、include Filtersなどの属性を使ってスキャンするパケットを指定したり、排除したりすることができます.スキャンの条件もあります.最終的にこれらのbean定義を容器にロードする.
@Enbale AutoConfigrationは、Spring Bootの構成をこのように簡略化できるようにするためのキー注釈であり、Spring-Bootは、アプリケーションによって宣言されたjarパケット依存性に基づいてSpringフレームを自動的に配置する.たとえば
spring-boot-starter-web
によると ,あなたのプロジェクトがwebmvc
とtomcat
を追加する必要があるかどうかを判断すると、自動的にウェブプロジェクトに必要なデフォルトの設定を設定してくれます.@Enbale AutoConfigration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
// EnableAutoConfigurationImportSelector
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class>[] exclude() default {};
String[] excludeName() default {};
}
種類のEnbaleAutoConfigrationImportSelectorはImport Selectorインターフェースの実現類であり、ImportSelectorインターフェースのselectImportsメソッドから戻ってくるクラスはSpring容器で管理されます.public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
try {
// META-INF/spring-autoconfigure-metadata.properties
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
//
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// classpath META-INF/spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration , List
List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
// List 、
configurations = this.removeDuplicates(configurations);
configurations = this.sort(configurations, autoConfigurationMetadata);
// 2
Set exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
// List , 。 org.springframework.boot.autoconfigure.condition.OnClassCondition ConditionOutcome[] 。
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return (String[])configurations.toArray(new String[configurations.size()]);
} catch (IOException var6) {
throw new IllegalStateException(var6);
}
}
}
}
この注釈@EnbaleAutoConfigration式はどうやって効果がありますか?メイン起動タイプのmain関数では、SpringAppleication.run(DemoApple.class,args)を呼び出して、2ステップに分けて実行します.第1ステップはSprigAplicationオブジェクトを作成し、第2ステップはrun方法を実行します.
第一歩、SpringAppleオブジェクトの作成
このステップの主な機能はSprigAplicationオブジェクトを初期化し、クラスパスの下からMETA-INF/spring.factores配置のすべてのApplizerとApplizerを見つけて保存して、最後にmainメソッドの主な構成クラスを見つけます.
private void initialize(Object[] sources) {
//
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
// web
this.webEnvironment = deduceWebEnvironment();
// META‐INF/spring.factories ApplicationContextInitializer;
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
// ETA‐INF/spring.factories ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// main
this.mainApplicationClass = deduceMainApplicationClass();
}
第二ステップ、運転run方法run方法の重要なポイントは、IOC容器context=createApple plication Contect();最後に起動したIOC容器に戻ります.途中でrefreshContent()を呼び出し、最後にspring容器のrefreshに呼び出した場合、
invokeBeanFactoryPostProcessors(beanFactory)
方法でConfigrationClass PostProcessorに呼び出します.ConfigrationClass PostProcessorは私達のメインクラスを解析して@Import
の中のクラスを取り出して、そのselectImports()
の方法を呼び出します.その後spring容器はselectInportメソッドから返される配置類を処理します.public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
// SpringApplicationRunListeners; META‐INF/spring.factories
SpringApplicationRunListeners listeners = getRunListeners(args);
// SpringApplicationRunListener.starting()
listeners.starting();
try {
//
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
// SpringApplicationRunListener.environmentPrepared();
Banner printedBanner = printBanner(environment);
// ApplicationContext; web ioc ioc
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
// ; environment ioc ; applyInitializers();
//applyInitializers(): ApplicationContextInitializer initialize
// SpringApplicationRunListener contextPrepared();
//
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//prepareContext SpringApplicationRunListener contextLoaded();
//s ;ioc ( web Tomcat);Spring
// , , ;( , , )
refreshContext(context);
// ioc ApplicationRunner CommandLineRunner
//ApplicationRunner ,CommandLineRunner
afterRefresh(context, applicationArguments);
// SpringApplicationRunListener finished
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
// SpringBoot ioc ;
return context;
} catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}