@toc
Обзор: Эта статья начинается с чтения файла конфигурации по умолчанию, то есть пользовательского файла конфигурации, чтобы разобраться и понять различия между несколькими схемами загрузки и несколькими способами, которыми SpringBoot читает файлы конфигурации.
Вывод: независимо от сценария рекомендуется использовать аннотацию @Value, чтобы подготовить ошибки и просто понять остальные.
Каталог файлов конфигурации
application.properties
server.port=8080
spring.profiles.active=dev
application-dev.properties
spring.redis.host=localhost
logging.level.root = info
application-prod.properties
spring.redis.port=6379
logging.level.root = warn
my.properties
demo.name=cat
<font color='red'>Примечание1:</font>
Environment — это класс, используемый для чтения переменных среды во время работы приложения. Он может читать переменные application.properties и системной среды, входные параметры командной строки, свойства системы и т. д. в виде ключ-значение.
Controller
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Проверьте несколько способов чтения файла конфигурации:
* @Author 211145187
* @Date 2022/7/20 14:02
**/
@RestController
public class ReadApplicationProperties {
@Autowired
private Environment environment;
//Метод тестирования 1: чтение информации о конфигурации через среду.
@GetMapping("/readApplicationProperties1")
public Map<String,Object> readApplicationProperties1(){
Map<String,Object> map = new HashMap<>();
map.put("port",environment.getProperty("server.port"));
System.out.println("Читать информацию о конфигурации через среду:" + environment.getProperty("server.port"));
return map;
}
}
Результат печатает:
Controller
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Проверьте несколько способов чтения файла конфигурации:
* @Author 211145187
* @Date 2022/7/20 14:02
**/
@RestController
public class ReadApplicationProperties {
@Value("${server.port}")
private Integer serverPort;
//Метод тестирования 2: чтение информации о конфигурации через аннотацию @Value
@GetMapping("/readApplicationProperties2")
public void readApplicationProperties2(){
System.out.println("Читать информацию о конфигурации через аннотацию @Value:" + serverPort);
}
}
Печать результатов
<font color='red'>Примечание1:</font>
<font color='red'>@ConfigurationPropertiesАннотации используются для указания префиксов.,Имя атрибута «из», приведенное ниже, должно соответствовать имени получаемой информации о конфигурации.,Например, он должен называться портом,В противном случае полученное значениеnull</font>
Используйте @ConfigurationProperties, чтобы сначала установить связь между файлами конфигурации и объектами, а затем используйте аннотацию @Autowired в методе контроллера для внедрения объекта.
<font color='red'>Примечание2:</font>
<font color='red'>Конфигурация вступает в силуиздва пути:</font>
<font color='red'>Способ1:</font>Конфигурация@Component
<font color='red'>Способ2:</font>Добавлен класс запуска@EnableConfigurationProperties(ReadProperties.class)
<font color='red'>Подвести Итог: аннотация @Component и аннотация @EnableConfigurationProperties(ReadProperties.class) эквивалентны,Просто напишите один。</font>
<font color='red'>Примечание3:</font>
@ConfigurationProperties также можно использовать с @Value и @Bean, но я не писал случай.
<font color='red'>Примечание4:</font>
@ConfigurationProperties может загружать только файлы конфигурации, начинающиеся с префикса application, например application-dev.properties. Загрузка содержимого файла конфигурации с собственным именем недействительна.
<font color='red'>Примечание5:</font>
Вопрос: Из приведенного выше примера мы видим, что @EnableConfigurationProperties и @Component имеют одинаковый эффект при привязке свойств, так почему же Springboot все еще использует эту аннотацию?
<font color='red'>Отвечать:</font>Когда мы ссылаемся на третьи лицаjarВремя упаковки,Класс аннотации @Component нельзя внедрить в контейнер Spring.,На данный момент мы можем использовать @EnableConfigurationProperties вместо @Component.
ReadProperties
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 1) изпрефикс в аннотации @ConfigurationProperties используется для установки префикса
* 2) Имя атрибута ниже должно соответствовать имени получаемой информации о конфигурации. Например, он должен называться портом, иначе полученное значение будет нулевым.
*/
@ConfigurationProperties(prefix = "server")//Эта аннотация используется для поиска класса
@Component //Два способа вступления в силу: метод 1: настроить @Component, метод 2: добавить @EnableConfigurationProperties(ReadProperties.class) в класс запуска
@Data
public class ReadProperties {
private Integer port;
}
Controller
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Проверьте несколько способов чтения файла конфигурации:
* @Author 211145187
* @Date 2022/7/20 14:02
**/
@RestController
public class ReadApplicationProperties {
@Autowired
private ReadProperties readProperties;
//Метод тестирования 3: чтение информации о конфигурации через аннотацию @ConfigurationProperties.
@GetMapping("/readApplicationProperties3")
public void readApplicationProperties3(){
System.out.println("Читать информацию о конфигурации через аннотацию @ConfigurationProperties:" + readProperties.getPort());
}
}
Печать результатов
<font color='red'>Примечание1:</font>
Аннотация @PropertySource загружает указанный файл свойств (*.properties) в среду Spring. Может использоваться с @Value, @ConfigurationProperties и @Bean.
<font color='red'>Примечание2:</font>
Аннотацию @PropertySource можно использовать с @Value, @ConfigurationProperties и @Bean, но я не писал случая.
<font color='red'>Примечание3:</font>
При использовании аннотации @PropertySource рекомендуется загружать файлы конфигурации только с пользовательскими именами. Не загружайте файлы конфигурации, начинающиеся с префикса application, например application-dev.properties, поскольку значения ключей с повторяющимися именами будут перезаписаны. . Это будет отмечено в пункте 4. Акцент.
<font color='red'>Примечание4:(наиболее подвержен ошибкам)</font>
Объясните большую яму
<font color='red'>Дополнительная информация:</font>application-dev.propertiesСредние настройкиlogging.level.root = info, а logging.level.root установлен в application-prod.properties. = warn
<font color='red'>Описание случая:</font>application.propertiesКонфигурация文件设置内置spring.profiles.active=dev,Используется для связи файла конфигурации application-dev.properties.,При нормальной работе кода в память загружаются файлы конфигурации application.properties и application-dev.properties.,Но теперь я хочу создать конфигурацию или компонент,проходить@PropertySourceаннотация去注入并打印application-prod.propertiesсерединаизэтот контент:logging.level.root = alert, результатом правильной печати logging.level.root должно быть предупреждение, поскольку он загружается последним, но фактическое значение logging.level.root — это info.
Вопрос: Почему? Почему печатается информация, но я хочу напечатать предупреждение о значении в prod
<font color='red'>Отвечать:</font>Как показано на картинке1,Посмотрите на красное поле и вы почувствуете, что прод загружается и загружается в инфо.,Вы подумаете, что тот же самый ключ в prod перезапишет значение из в dev.,Фактический ответ на самом деле не такой,Подробности см. в ответе этого человека на рисунке 2. Обычно в производственных проектах разрешено использовать только один файл application-dev.properties и application-prod.properties.,Они не будут смешиваться.
<font color='red'>Фактическое реальное проектное решение:
<center><font color='red'>Как показано на картинке1</font></center>
<center><font color='red'>Как показано на картинке2</font></center>
<font color='red'>Примечание5:</font>
Приоритет загрузки файла конфигурации > @PropertySource внедрение аннотаций
ReadProperties2
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* @Author 211145187
* @Date 2022/7/20 15:47
**/
@PropertySource(value = {"application.properties"})
@Component
@Data
public class ReadProperties2 {
@Value("${server.port}")
private Integer port;
}
ReadProperties4
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* @Author 211145187
* @Date 2022/7/20 15:51
**/
@ConfigurationProperties(prefix = "spring.redis")//Эта аннотация используется для поиска класса Примечание. @ConfigurationProperties не может загружать пользовательское содержимое запроса конфигурации и его необходимо использовать вместе с @PropertySource для его получения.
@Component //Два способа вступления в силу: метод 1: настроить @Component, метод 2: добавить @EnableConfigurationProperties(ReadProperties.class) в класс запуска
@PropertySource(value = {"classpath:application-prod.properties"})
@Data
public class ReadProperties4 {
private String port;
}
Controller
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Проверьте несколько способов чтения файла конфигурации:
* @Author 211145187
* @Date 2022/7/20 14:02
**/
@RestController
public class ReadApplicationProperties {
@Autowired
private ReadProperties2 readProperties2;
//Метод тестирования 4. Считайте информацию о конфигурации с помощью аннотации @PropertySource+@Value.
@GetMapping("/readApplicationProperties4")
public void readApplicationProperties4(){
System.out.println("Читать информацию о конфигурации через аннотацию @PropertySource:" + readProperties2.getPort());
}
}
Печать результатов
ReadProperties3
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* @Author 211145187
* @Date 2022/7/20 15:51
**/
@ConfigurationProperties(prefix = "demo")//Эта аннотация используется для поиска класса Примечание. @ConfigurationProperties не может загружать пользовательское содержимое запроса конфигурации и его необходимо использовать вместе с @PropertySource для его получения.
@Component //Два способа вступления в силу: метод 1: настроить @Component, метод 2: добавить @EnableConfigurationProperties(ReadProperties.class) в класс запуска
@PropertySource(value = {"classpath:my.properties"})
@Data
public class ReadProperties3 {
private String name;
}
Controller
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Проверьте несколько способов чтения файла конфигурации:
* @Author 211145187
* @Date 2022/7/20 14:02
**/
@RestController
public class ReadApplicationProperties {
@Autowired
private ReadProperties3 readProperties3;
//Метод тестирования 5. Считайте информацию о конфигурации с помощью аннотации @PropertySource+@ConfigurationProperties.
@GetMapping("/readApplicationProperties5")
public void readApplicationProperties5(){
System.out.println("Читать информацию о конфигурации через аннотацию @PropertySource+@ConfigurationProperties:" + readProperties3);
}
}
Печать результатов
Controller
import com.example.demo.config.ReadProperties;
import com.example.demo.config.ReadProperties2;
import com.example.demo.config.ReadProperties3;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* Проверьте несколько способов чтения файла конфигурации:
* @Author 211145187
* @Date 2022/7/20 14:02
**/
@RestController
public class ReadApplicationProperties {
//Метод проверки 6. Считайте информацию о конфигурации через «Свойства».
@GetMapping("/readApplicationProperties6")
public void readApplicationProperties6() throws IOException {
Resource resource = new ClassPathResource("application-prod.properties");
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
String root = properties.getProperty("logging.level.root");
System.out.println("Читать информацию о конфигурации через xProperties:" + root);
}
}
Печать результатов