目次
pom.xml
父方の依存
親プロジェクトは主に親プロジェクトに依存しており、主にプロジェクトのリソースフィルタリングとプラグインを管理します。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
クリックして、別の親の依存関係があることを確認します
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
これは、SpringBootのバージョン管理センターであるSpringBootアプリケーションのすべての依存バージョンを真に管理する場所です。
将来的には、バージョンを書き込まずにデフォルトで依存関係をインポートしますが、インポートされたパッケージが依存関係で管理されていない場合は、バージョンを手動で構成する必要があります。
ランチャー
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
springboot-boot-starter-xxx:はspring-bootのシーンスターターです
spring-boot-starter-web:通常の操作でWebモジュールが依存するコンポーネントをインポートするのを手伝ってください。
SpringBootは、すべての機能シナリオを1つのスターター(スターター)に抽出します。これらのスターターをプロジェクトに導入するだけで、関連するすべての依存関係がインポートされ、使用する関数の種類がインポートされます。シーンスターターで十分です。また、将来的には自分でスターターをカスタマイズします。
メインスタートクラス
//@SpringBootApplication 来标注一个主程序类
//说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
//以为是启动了一个方法,没想到启动了一个服务
SpringApplication.run(SpringbootApplication.class, args);
}
}
@SpringBootApplication
機能:特定のクラスに注釈を付けて、このクラスがSpringBootのメイン構成クラスであることを示します。SpringBootはこのクラスのmainメソッドを実行して、SpringBootアプリケーションを起動する必要があります。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {
@Filter(
type = FilterType.CUSTOM,
classes = {
TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {
AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
// ......
}
@ComponentScan
jは、XML構成の要素に対応します。
機能:修飾されたコンポーネントまたはBeanを自動的にスキャンしてロードし、このBean定義をIOCコンテナーにロードします
@SpringBootConfiguration
機能:特定のクラスでマークされたSpringBootの構成クラスは、これがSpringBootの構成クラスであることを示します。
引き続きこの注釈を表示して表示します
// 点进去得到下面的 @Component
@Configuration
public @interface SpringBootConfiguration {
}
@Component
public @interface Configuration {
}
ここでの@Configurationは、これが構成クラスであり、構成クラスがSpringに対応するxml構成ファイルであることを意味します。
内部の@Componentは、スタートアップクラス自体がSpringの単なるコンポーネントであり、アプリケーションの起動を担当することを意味します。
@EnableAutoConfiguration
@EnableAutoConfigurationは、自動構成機能をオンにして自動構成を有効にするようにSpringBootに指示します。
@ AutoConfigurationPackage:自動構成パッケージ
@Import({
Registrar.class})
public @interface AutoConfigurationPackage {
}
@import:スプリングボトムアノテーション@import、コンポーネントをコンテナにインポートします
Registrar.class関数:メインのスタートアップクラスが配置されているパッケージ内のすべてのコンポーネントと、パッケージの下にあるすべてのサブパッケージをSpringコンテナにスキャンします。
この分析が終わったら、前のステップに戻って読み続けてください
@Import({AutoConfigurationImportSelector.class}):コンポーネントをコンテナにインポートします。
AutoConfigurationImportSelector:インポートセレクターを自動的に構成します。どのコンポーネントセレクターをインポートしますか?クリックしてこのカテゴリに移動し、ソースコードを確認します。
// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//这里的getSpringFactoriesLoaderFactoryClass()方法
//返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
メソッドが呼び出されます(SpringFactoriesLoaderクラスの静的メソッド)
SpringFactoriesLoaderクラスloadFactoryNames()メソッド
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
//这里它又调用了 loadSpringFactories 方法
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
loadSpringFactories方法
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
//获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
//去获取一个资源 "META-INF/spring.factories"
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
//将读取到的资源遍历,封装成为一个Properties
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
String factoryClassName = ((String)entry.getKey()).trim();
String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
int var10 = var9.length;
for(int var11 = 0; var11 < var10; ++var11) {
String factoryName = var9[var11];
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var13) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
}
}
}
複数回出現したファイルが見つかりました:spring.factories
spring.factories
spring.factoriesを開いて、多くの自動構成ファイルを確認してください。これが自動構成のルートです。
したがって、自動構成の実際の実装は、クラスパスからすべてのMETA-INF / spring.factories構成ファイルを検索し、対応するorg.springframework.boot.autoconfigure。パッケージの下の構成アイテムをリフレクションを通じて対応するアノテーションにインスタンス化することです。 @Configuration JavaConfigの形式のIOCコンテナー構成クラス。これは、インスタンスに集約され、IOCコンテナーにロードされます。
総括する
-
SpringBootが起動すると、クラスパスの下のMETA-INF /spring.factoriesからEnableAutoConfigurationで指定された値を取得します。
-
これらの値を自動構成クラスとしてコンテナーにインポートすると、自動構成クラスが有効になり、自動構成作業に役立ちます。
-
J2EEの全体的なソリューションと自動構成は、springboot-autoconfigureのjarパッケージに含まれています。
-
多くの自動構成クラス(xxxAutoConfiguration)をコンテナーにインポートします。つまり、このシナリオに必要なすべてのコンポーネントをコンテナーにインポートし、これらのコンポーネントを構成します。
自動構成クラスを使用すると、構成インジェクション機能コンポーネントを手動で作成する作業を回避できます。
SpringApplicationクラス
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
SpringApplication.run分析
このメソッドの分析は、主に2つの部分に分かれています。1つはSpringApplicationのインスタンス化であり、もう1つはrunメソッドの実行です。
このクラスは主に次の4つのことを行います。
1.アプリケーションのタイプが通常のプロジェクトであるかWebプロジェクトであるかを推測します
2.使用可能なすべての初期化子を見つけてロードし、それらを初期化子プロパティに設定します
3.すべてのアプリケーションリスナーを見つけて、それらをlistenersプロパティに設定します
4. mainメソッドの定義クラスを推測して設定し、実行されるメインクラスを見つけます
1.コンストラクターを表示します。
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
// ......
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.setInitializers(this.getSpringFactoriesInstances();
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}