Spring Boot之常見問題解惑

FailureAnalyzer

FailureAnalyzer 用於攔截我們感興趣的異常,並將其包裝到更具可讀性的 FailureAnalysis ,比如application-context相關的異常,默認的實現AbstractFailureAnalyzer 繼承於 FailureAnalyzer ,用於檢查是否出現了特定的異常。如果需要訪問到BeanFactoryEnvironment,可以實現BeanFactoryAware orEnvironmentAware接口。對於處理不了的異常,我們直接返回 null 以便其他分析器可以處理。FailureAnalyzer 應該配置在 META-INF/spring.factories.才能生效,如:ProjectConstraintViolationFailureAnalyzer

org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer

Auto-configuration

Spring Boot自動配置提供了很多默認設置,方便我們快速建立一個spring boot應用,但是也常常讓我們感覺對具體的配置失去了控制,往往有問題也不知道從哪查起。調試的我們可以利用 ConditionEvaluationReport 來輸出具體的配置信息。如果添加了 spring-boot-actuator 模塊,可以在 conditions 端點看到JSON格式的配置信息。更多的時候可能需要我們自己去看源碼:

首先可以看 *AutoConfiguration 結尾的自動配置類,裏面一般有很多 @Conditional* 開頭的約束註解。這些表明在什麼時候啓用哪些配置,可以通過 --debug 或系統參數 -Ddebug 打開查看自動配置的日誌,在Actuator模塊的 conditions 端點也可以看到相關信息 (/actuator/conditions )

查看 @ConfigurationProperties 註解(比如 ServerProperties),通過這裏讀取外部配置項,這個註解有一個 name 屬性表明了配置項的前綴。比如 ServerProperties(name="server") 則讀取 server.port, server.address等,在Actuator  configprops 端點也可以看到。

查看Binder類的 bind 方法,用於顯示的綁定 Environment 參數,以及 @Value  @ConditionalOnExpression 等註解。

 

Customize 

SpringApplication可以添加多個 ApplicationListeners和ApplicationContextInitializers來實現在啓動前對context或environment的自定義。比如Spring Boot就通過 META-INF/spring.factories加載很多配置項。我們也可以添加自己的配置項:

可以直接在代碼中調用SpringApplication addListeners和addInitializers方法來添加;

也可以通過配置文件application.properties裏面的 context.initializer.classes 和

context.listener.classes properties項;

如果是針對所有應用生效則可以添加 META-INF/spring.factories,並打成jar包來引用。

SpringApplication會發送一些特定的 ApplicationEvents到listeners (有些是在context被創建之前的),然後將這些listeners註冊到 ApplicationContext。

同時還可以通過實現EnvironmentPostProcessor接口,在Environment刷新之前添加配置,同樣實現類也需要配到META-INF/spring.factories,如

org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor

如下實現了從classpath加載YAML文件到Environment:

package hello;

import java.io.IOException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {

	private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();

	@Override
	public void postProcessEnvironment(ConfigurableEnvironment environment,
			SpringApplication application) {
		Resource path = new ClassPathResource("com/example/myapp/config.yml");
		PropertySource<?> propertySource = loadYaml(path);
		environment.getPropertySources().addLast(propertySource);
	}

	private PropertySource<?> loadYaml(Resource path) {
		if (!path.exists()) {
			throw new IllegalArgumentException("Resource " + path + " does not exist");
		}
		try {
			return this.loader.load("custom-resource", path, null);
		}
		catch (IOException ex) {
			throw new IllegalStateException(
					"Failed to load yaml configuration from " + path, ex);
		}
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章