Java for Beginner
675 subscribers
558 photos
156 videos
12 files
852 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Properties, особенности и внутреннее устройство

Properties — это подкласс Hashtable, который используется для хранения ключей и значений в виде строк. Этот класс особенно полезен для хранения конфигурационных данных, таких как настройки приложений, пути к файлам, параметры базы данных и другие подобные параметры.

Основные характеристики Properties:

Наследование от Hashtable: Properties наследуется от класса Hashtable, что позволяет ему использовать все методы и возможности, предоставляемые Hashtable, такие как вставка, удаление, поиск и итерация по элементам.
Хранение только строк: В отличие от Hashtable,
Properties хранит только строки в качестве ключей и значений. Это делает его удобным для работы с текстовыми конфигурациями.
Поддержка файлов:
Properties предоставляет методы для загрузки и сохранения данных из/в файлы в формате .properties, что делает его идеальным для хранения конфигурационных файлов.

Внутреннее устройство класса Properties

Класс Properties реализован на основе хеш-таблицы, что позволяет эффективно хранить и извлекать данные. Однако, чтобы глубже понять, как работает Properties, давайте рассмотрим его внутреннее устройство.
public class Properties extends Hashtable<Object, Object> {
// Хранение значений по умолчанию
protected Properties defaults;

// Конструкторы
public Properties() {
this(null);
}

public Properties(Properties defaults) {
this.defaults = defaults;
}

// Основные методы
public String getProperty(String key) {
Object oval = super.get(key);
String sval = (oval instanceof String) ? (String)oval : null;
return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}

public String getProperty(String key, String defaultValue) {
String val = getProperty(key);
return (val == null) ? defaultValue : val;
}

public Object setProperty(String key, String value) {
return put(key, value);
}

// Методы для работы с файлами
public void load(InputStream inStream) throws IOException {
// ...
}

public void store(OutputStream out, String comments) throws IOException {
// ...
}
}


Основные компоненты:

Наследование от Hashtable: Класс Properties наследует функциональность от Hashtable, что позволяет ему использовать хеширование для быстрого доступа к элементам.
Поля defaults: Поле defaults позволяет определить другой объект
Properties, который будет использоваться для предоставления значений по умолчанию, если ключ не найден в текущем объекте.
Методы getProperty() и setProperty(): Эти методы являются основными для работы с парами "ключ-значение" и обеспечивают удобный интерфейс для получения и установки свойств.
Методы load() и store(): Эти методы используются для загрузки свойств из файла и сохранения их обратно в файл. Формат файла .
properties поддерживает простую структуру текста, где каждая строка представляет собой пару "ключ=значение".

Формат файлов .properties

Файлы с расширением .properties содержат конфигурационные данные в текстовом формате. Эти файлы широко используются для хранения настроек приложений, переводов и других данных, которые могут изменяться без необходимости изменения исходного кода.

Пример файла config.properties:
database.url=jdbc:mysql://localhost:3306/mydb
database.username=root
database.password=12345
Файл .properties имеет простой формат: каждая строка представляет собой пару "ключ=значение". Комментарии могут быть добавлены с помощью символов # или ! в начале строки.


#Java #Training #Medium #Properties
Особенности работы с Properties

Преемственность значений по умолчанию:
Одной из интересных возможностей Properties является возможность указания значений по умолчанию. Например, вы можете создать объект Properties, который будет содержать значения по умолчанию, и передать его в другой объект Properties.
Properties defaults = new Properties();
defaults.setProperty("language", "English");

Properties config = new Properties(defaults);
config.setProperty("database.url", "jdbc:mysql://localhost:3306/mydb");

System.out.println(config.getProperty("language")); // Выведет: English
В данном примере, если запрашиваемое свойство не найдено в объекте config, оно будет искаться в объекте defaults.


Работа с файлами:
Одним из ключевых преимуществ Properties является его возможность загружать и сохранять свойства в файлы. Это особенно полезно для создания конфигурационных файлов, которые могут быть изменены без перекомпиляции приложения.
try (FileInputStream input = new FileInputStream("config.properties")) {
Properties config = new Properties();
config.load(input);
System.out.println(config.getProperty("database.url"));
} catch (IOException e) {
e.printStackTrace();
}
В этом примере Properties загружаются из файла config.properties, и после этого можно получить доступ к его значениям.


Обработка строковых значений:
Properties работают исключительно с строками, поэтому любые данные, которые необходимо хранить, должны быть преобразованы в строки. Это накладывает определенные ограничения, но также упрощает сериализацию и десериализацию данных.

Управление локализацией:
Properties часто используются в связке с ResourceBundle для управления переводами и локализацией в приложениях. Это позволяет легко поддерживать несколько языков в приложении, используя различные файлы .properties для каждого языка.

Ссылки на полезные статьи (спасибо авторам за проделанную работу) :

https://www.baeldung.com/java-properties
https://www.geeksforgeeks.org/java-util-properties-class-java/

#Java #Training #Medium #Properties
Основные методы Properties и примеры использования

setProperty(String key, String value):
Этот метод используется для добавления или обновления пары "ключ-значение" в объекте Properties.
Properties config = new Properties();
config.setProperty("database.url", "jdbc:mysql://localhost:3306/mydb");
config.setProperty("database.username", "root");
config.setProperty("database.password", "12345");
В этом примере мы создаем объект Properties и устанавливаем три свойства: URL базы данных, имя пользователя и пароль.


getProperty(String key):
Метод getProperty() позволяет получить значение свойства по его ключу. Если ключ не найден, метод вернет null.
String url = config.getProperty("database.url");
System.out.println("Database URL: " + url);
В этом примере значение свойства database.url извлекается и выводится на консоль.


getProperty(String key, String defaultValue):
Этот метод позволяет указать значение по умолчанию, которое будет возвращено в случае, если ключ не найден в объекте Properties.
String timeout = config.getProperty("connection.timeout", "30");
System.out.println("Connection timeout: " + timeout);
Если свойство connection.timeout не будет найдено, метод вернет значение "30".


load(InputStream inStream):
Метод load() загружает свойства из потока ввода (например, из файла).
try (FileInputStream input = new FileInputStream("config.properties")) {
Properties config = new Properties();
config.load(input);
} catch (IOException e) {
e.printStackTrace();
}
В этом примере свойства загружаются из файла config.properties.


store(OutputStream out, String comments):
Метод store() сохраняет свойства в выходной поток (например, в файл). Метод также позволяет добавить комментарии, которые будут записаны в начале файла.
try (FileOutputStream output = new FileOutputStream("config.properties")) {
config.store(output, "Database Configuration");
} catch (IOException e) {
e.printStackTrace();
}
В этом примере свойства сохраняются в файл config.properties, и в файл добавляется комментарий "Database Configuration".


propertyNames():
Метод propertyNames() возвращает перечисление всех ключей, содержащихся в объекте Properties.
Enumeration<?> propertyNames = config.propertyNames();
while (propertyNames.hasMoreElements()) {
String key = (String) propertyNames.nextElement();
System.out.println("Key: " + key + ", Value: " + config.getProperty(key));
}
В этом примере мы перебираем все ключи и выводим их вместе с соответствующими значениями.


stringPropertyNames():
Этот метод возвращает набор всех ключей, которые представлены строками.
Set<String> keys = config.stringPropertyNames();
for (String key : keys) {
System.out.println("Key: " + key + ", Value: " + config.getProperty(key));
}
stringPropertyNames() полезен, когда нужно работать с Set, а не с Enumeration.


remove(String key):
Метод remove() удаляет свойство по указанному ключу.
config.remove("database.password");
В этом примере удаляется свойство database.password.


clear():
Метод clear() очищает все свойства из объекта Properties.
config.clear();
После вызова этого метода все свойства будут удалены из объекта Properties.


#Java #Training #Medium #Properties
Примеры использования класса Properties

Пример 1: Загрузка и сохранение конфигурации приложения
Часто приложения требуют загрузки конфигурационных параметров из файла при старте и их сохранения при завершении.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class AppConfig {
private Properties config = new Properties();
private String configFilePath;

public AppConfig(String configFilePath) {
this.configFilePath = configFilePath;
loadConfig();
}

public void loadConfig() {
try (FileInputStream input = new FileInputStream(configFilePath)) {
config.load(input);
} catch (IOException e) {
e.printStackTrace();
}
}

public void saveConfig() {
try (FileOutputStream output = new FileOutputStream(configFilePath)) {
config.store(output, "Application Configuration");
} catch (IOException e) {
e.printStackTrace();
}
}

public String getSetting(String key, String defaultValue) {
return config.getProperty(key, defaultValue);
}

public void setSetting(String key, String value) {
config.setProperty(key, value);
}

public static void main(String[] args) {
AppConfig appConfig = new AppConfig("app.properties");

// Получение настроек
String url = appConfig.getSetting("database.url", "jdbc:mysql://localhost:3306/defaultdb");
System.out.println("Database URL: " + url);

// Установка и сохранение настроек
appConfig.setSetting("app.theme", "dark");
appConfig.saveConfig();
}
}
В этом примере класс AppConfig управляет загрузкой и сохранением конфигурации приложения, хранящейся в файле app.properties.


Пример 2: Локализация с использованием ResourceBundle
Класс Properties может использоваться совместно с ResourceBundle для реализации локализации приложения. Например, хранение сообщений на разных языках в отдельных файлах .properties.
import java.util.Locale;
import java.util.ResourceBundle;

public class LocalizationExample {
public static void main(String[] args) {
Locale currentLocale = new Locale("en", "US");
ResourceBundle messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);

System.out.println(messages.getString("greeting"));
}
}
Предположим, у нас есть два файла:

MessagesBundle_en_US.properties:

makefile
Копировать код
greeting=Hello!
MessagesBundle_fr_FR.properties:

makefile
Копировать код
greeting=Bonjour!
В зависимости от выбранной локали, приложение будет загружать соответствующий файл и использовать правильные сообщения.


Пример 3: Автозаполнение настроек по умолчанию
Иногда нужно использовать настройки по умолчанию, если они не указаны в конфигурационном файле.
import java.util.Properties;

public class DefaultSettingsExample {
public static void main(String[] args) {
Properties defaults = new Properties();
defaults.setProperty("app.theme", "light");
defaults.setProperty("app.language", "en");

Properties config = new Properties(defaults);
config.setProperty("app.theme", "dark");

System.out.println("Theme: " + config.getProperty("app.theme")); // Вывод: dark
System.out.println("Language: " + config.getProperty("app.language")); // Вывод: en
}
}
Здесь Properties использует значения по умолчанию, если они не были переопределены в основном конфигурационном объекте.


#Java #Training #Medium #Properties
Пример 4: Хранение пользовательских настроек
Предположим, у нас есть приложение, которое позволяет пользователям изменять настройки интерфейса, такие как тема или язык. Эти настройки можно сохранять в файл Properties, чтобы при следующем запуске приложения они автоматически подгружались.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class UserSettings {
private Properties settings = new Properties();
private String settingsFilePath;

public UserSettings(String settingsFilePath) {
this.settingsFilePath = settingsFilePath;
loadSettings();
}

private void loadSettings() {
try (FileInputStream input = new FileInputStream(settingsFilePath)) {
settings.load(input);
} catch (IOException e) {
System.out.println("Using default settings.");
}
}

public void saveSettings() {
try (FileOutputStream output = new FileOutputStream(settingsFilePath)) {
settings.store(output, "User Settings");
} catch (IOException e) {
e.printStackTrace();
}
}

public String getTheme() {
return settings.getProperty("theme", "light");
}

public void setTheme(String theme) {
settings.setProperty("theme", theme);
}

public String getLanguage() {
return settings.getProperty("language", "en");
}

public void setLanguage(String language) {
settings.setProperty("language", language);
}

public static void main(String[] args) {
UserSettings userSettings = new UserSettings("user.properties");

System.out.println("Current theme: " + userSettings.getTheme());
System.out.println("Current language: " + userSettings.getLanguage());

userSettings.setTheme("dark");
userSettings.setLanguage("fr");
userSettings.saveSettings();
}
}
В этом примере пользовательские настройки хранятся в файле user.properties и загружаются при запуске приложения. Пользователь может изменить тему и язык, и эти изменения сохраняются для последующего использования.


#Java #Training #Medium #Properties
Способы работы с внешними конфигурациями в Spring: application.properties и application.yml

Spring Framework предоставляет мощные механизмы для работы с конфигурационными файлами, которые позволяют удобно управлять настройками приложения без необходимости перекомпиляции кода. В основном используются два формата файлов для хранения конфигураций — это application.properties и application.yml. Оба файла позволяют задавать параметры приложения, такие как настройки подключения к базе данных, порты сервера и другие ключевые свойства.

1. Работа с application.properties

Формат application.properties является традиционным для Spring и состоит из набора пар ключ-значение. Этот файл обычно размещается в папке src/main/resources и загружается автоматически при старте приложения Spring Boot.

1.1. Пример application.properties
# Настройки сервера
server.port=8081

# Настройки базы данных
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root

# Логирование
logging.level.org.springframework=INFO


1.2. Чтение свойств из
application.properties

Для того чтобы использовать значения из конфигурационного файла, можно воспользоваться аннотацией @Value. Эта аннотация позволяет внедрять значение конфигурационного параметра в поле или метод класса.

Пример внедрения значения из application.properties:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MyService {

@Value("${server.port}")
private int serverPort;

public void printPort() {
System.out.println("Порт сервера: " + serverPort);
}
}
В этом примере значение из параметра server.port будет внедрено в переменную serverPort.


1.3. Использование @ConfigurationProperties

Для работы с большим количеством связанных настроек можно использовать аннотацию @ConfigurationProperties, которая автоматически связывает свойства из конфигурационного файла с полями Java-класса.

Пример использования @ConfigurationProperties:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceConfig {

private String url;
private String username;
private String password;

// Геттеры и сеттеры
}
Здесь класс DataSourceConfig автоматически связывается с параметрами, которые начинаются с префикса spring.datasource в файле application.properties.


#Java #Training #Spring #properties