springboot (три) — при разборе application.properties и application.yml

Java
springboot (три) — при разборе application.properties и application.yml

предисловие

Друзья, которые использовали springboot, знают, что springboot не нужно вводить столько файлов конфигурации, как springmvc, а нужно только добавить application.properties или application.yml, Например, в предыдущей статье я говорил о настройке базы данных , Файл представляет следующую конфигурацию:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/zplxjj?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=@ZPLxjj12345
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Ниже приведено краткое введение в содержимое файлов свойств и файлов yml, которые Springboot считывает при запуске.

Реализовать простой пользовательский слушатель

первый шаг: определить событие, унаследовать ApplicationEvent

public class CustomerApplicationEvent extends ApplicationEvent {
    public CustomerApplicationEvent(Object source) {
        super(source);
        System.out.println("CustomerApplicationEvent constructor...");
    }
}

второй шаг: определить слушателя

@Component
public class CustomerApplicationListener implements ApplicationListener<CustomerApplicationEvent> {

    @Override
    public void onApplicationEvent(CustomerApplicationEvent customerApplicationEvent) {
        System.out.println("customerApplicationEvent:"+customerApplicationEvent.getClass().getName());
    }
}

третий шаг: зарегистрировать слушателя

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        // 注册 CustomerApplicationListener 事件监听器
        context.addApplicationListener(new CustomerApplicationListener());
        // 发布 CustomerApplicationEvent 事件
        context.publishEvent(new CustomerApplicationEvent(new Object()));
    }
}

После запуска проекта вы увидите вывод консоли:

CustomerApplicationEvent constructor...
customerApplicationEvent:com.stone.zplxjj.event.CustomerApplicationEvent

События, которые приходят с springboot

  • ApplicationStartingEvent: Событие запуска приложения.Перед вызовом метода SpringApplication.run() можно получить из него объект SpringApplication и выполнить некоторые предзапусковые настройки.
  • ApplicationEnvironmentPreparedEvent: среда готова для завершения события, затем вы можете получить среду и объект, элементы конфигурации которого нужно просмотреть или изменить..
  • ApplicationPreparedEvent: ApplicationContext готов завершить событие, а затем Spring может загрузить bean-компонент в контейнер.
  • ApplicationReadyEvent: приложение готово к завершению события, что указывает на то, что приложение может получить и обработать запрос.
  • ApplicationFailedEvent: событие сбоя запуска приложения, из которого можно получить информацию об исключении сбоя запуска для соответствующей обработки, такой как добавление перехватчиков, соответствующих виртуальным машинам, для перезапуска и освобождения ресурсов.

Чтение записи кода конфигурации: ApplicationEnvironmentPreparedEvent и ConfigFileApplicationListener

ConfigFileApplicationListener требуется для загрузки файла конфигурации, и его код выглядит следующим образом:

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof ApplicationEnvironmentPreparedEvent) {
			onApplicationEnvironmentPreparedEvent(
					(ApplicationEnvironmentPreparedEvent) event);
		}
		if (event instanceof ApplicationPreparedEvent) {
			onApplicationPreparedEvent(event);
		}
	}

Способ ввода: onApplicationEnvironmentPreparedEvent

	private void onApplicationEnvironmentPreparedEvent(
			ApplicationEnvironmentPreparedEvent event) {
		List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
		postProcessors.add(this);
		AnnotationAwareOrderComparator.sort(postProcessors);
		for (EnvironmentPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessEnvironment(event.getEnvironment(),
					event.getSpringApplication());
		}
	}

Введите postProcessor.postProcessEnvironment:

  //类:ConfigFileApplicationListener
	@Override
	public void postProcessEnvironment(ConfigurableEnvironment environment,
			SpringApplication application) {
		addPropertySources(environment, application.getResourceLoader());
	}

Введите addPropertySources

	protected void addPropertySources(ConfigurableEnvironment environment,
			ResourceLoader resourceLoader) {
        //将随机方法放入到PropertySources中
		RandomValuePropertySource.addToEnvironment(environment);
        //load加载
		new Loader(environment, resourceLoader).load();
	}

Введите метод загрузки:

		public void load() {
			this.profiles = new LinkedList<>();
			this.processedProfiles = new LinkedList<>();
			this.activatedProfiles = false;
			this.loaded = new LinkedHashMap<>();
			initializeProfiles();
			while (!this.profiles.isEmpty()) {
				Profile profile = this.profiles.poll();
				if (profile != null && !profile.isDefaultProfile()) {
					addProfileToEnvironment(profile.getName());
				}
				load(profile, this::getPositiveProfileFilter,
						addToLoaded(MutablePropertySources::addLast, false));
				this.processedProfiles.add(profile);
			}
			resetEnvironmentProfiles(this.processedProfiles);
			load(null, this::getNegativeProfileFilter,
					addToLoaded(MutablePropertySources::addFirst, true));
			addLoadedPropertySources();
		}

Введите слово метод загрузки

    private void load(Profile profile, DocumentFilterFactory filterFactory,
				DocumentConsumer consumer) {
			getSearchLocations().forEach((location) -> {
				boolean isFolder = location.endsWith("/");
				Set<String> names = isFolder ? getSearchNames() : NO_SEARCH_NAMES;
				names.forEach(
						(name) -> load(location, name, profile, filterFactory, consumer));
			});
		}
  • getSearchLocations(): сначала посмотрите на CONFIG_LOCATION_PROPERTY, если есть конфигурация, если нет, перейдите к пути конфигурации по умолчанию DEFAULT_SEARCH_LOCATIONS.
	/**
	 * The "config location" property name.
	 */
	public static final String CONFIG_LOCATION_PROPERTY = "spring.config.location";

	// Note the order is from least to most specific (last one wins)
	private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
  • getSearchNames(): сначала посмотрите на конфигурацию CONFIG_NAME_PROPERTY(spring.config.name), в противном случае перейдите к DEFAULT_NAMES(application)

**spring.config.name описание: **Если вам не нравится имя файла по умолчанию «application.properties», вы можете сбросить его: свойство spring.config.name напрямую указывает имя файла свойств, а свойство spring Свойство .config.location указывает Укажите путь, но будьте осторожны, не пропишите его в файле application.properties, это не сработает, вы можете написать его в java -jar xxx.jar --spring.config.name=custom. свойства или через переменные окружения и т. д. yml-файл также может это сделать

Способ фактической загрузки файла конфигурации:

		private void load(String location, String name, Profile profile,
				DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
			if (!StringUtils.hasText(name)) {
				for (PropertySourceLoader loader : this.propertySourceLoaders) {
					if (canLoadFileExtension(loader, location)) {
						load(loader, location, profile,
								filterFactory.getDocumentFilter(profile), consumer);
						return;
					}
				}
			}
			Set<String> processed = new HashSet<>();
			for (PropertySourceLoader loader : this.propertySourceLoaders) {
				for (String fileExtension : loader.getFileExtensions()) {
					if (processed.add(fileExtension)) {
						loadForFileExtension(loader, location + name, "." + fileExtension,
								profile, filterFactory, consumer);
					}
				}
			}
		}

loader.getFileExtensions(): Получить все поддерживаемые суффиксы файлов.Загрузчик инициализируется следующим образом:

		Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
			this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(
					PropertySourceLoader.class, getClass().getClassLoader());
		}

Загрузив соответствующий контент в файле jar:spring-boot-2.1.4.RELEASE.jar:META-INF/spring.factories:

# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

Отсюда мы можем видеть, что через PropertiesPropertySourceLoader и YamlPropertySourceLoader Загрузите файл конфигурации, конкретный исходный код не был внимательно прочитан, если вам интересно прочитать его самостоятельно

После загрузки файла конфигурации вызовите метод: addLoadedPropertySources()

Эпилог

До сих пор здесь был проанализирован вход в свойства загрузки springboot и yml Подробности не должны быть исчерпывающими, но если вход известен, его будет легко проанализировать позже.

Я также открыл публичный аккаунт в WeChat: stonezplxjj и личный блог:www.zplxjj.com, больше статей можно обратить внимание на общедоступный номер: