предисловие
Друзья, которые использовали 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, больше статей можно обратить внимание на общедоступный номер: