«1. Введение
В этом руководстве мы продемонстрируем различные способы доступа и загрузки содержимого файла, который находится в пути к классам, с помощью Spring.
2. Использование ресурсов
Интерфейс ресурсов помогает абстрагироваться от доступа к низкоуровневым ресурсам. Фактически, он поддерживает единую обработку всех видов файловых ресурсов.
Давайте начнем с рассмотрения различных методов получения экземпляра Resource.
2.1. Вручную
Для доступа к ресурсу из пути к классам мы можем просто использовать ClassPathResource:
public Resource loadEmployeesWithClassPathResource() {
return new ClassPathResource("data/employees.dat");
}
По умолчанию ClassPathResource удаляет некоторые шаблоны, выбирая между контекстным загрузчиком классов потока и системным загрузчиком классов по умолчанию.
Однако мы также можем указать загрузчик классов для использования либо напрямую:
return new ClassPathResource("data/employees.dat", this.getClass().getClassLoader());
Или косвенно через указанный класс:
return new ClassPathResource(
"data/employees.dat",
Employee.class.getClassLoader());
Обратите внимание, что из ресурса мы можем легко перейти к стандартным представлениям Java, таким как InputStream или Файл.
Еще одна вещь, которую следует отметить, это то, что описанный выше метод работает только для абсолютных путей. Если мы хотим указать относительный путь, мы можем передать второй аргумент класса. Путь будет относиться к этому классу:
new ClassPathResource("../../../data/employees.dat", Example.class).getFile();
Указанный выше путь к файлу относится к классу Example.
2.2. Использование @Value
Мы также можем внедрить ресурс с помощью @Value:
@Value("classpath:data/resource-data.txt")
Resource resourceFile;
@Value также поддерживает другие префиксы, такие как file: и url:.
2.3. Использование ResourceLoader
Если мы хотим лениво загрузить наш ресурс, мы можем использовать ResourceLoader:
@Autowired
ResourceLoader resourceLoader;
Затем мы извлекаем наш ресурс с помощью getResource:
public Resource loadEmployeesWithResourceLoader() {
return resourceLoader.getResource(
"classpath:data/employees.dat");
}
Также обратите внимание, что ResourceLoader реализуется всеми конкретными ApplicationContexts, это означает, что мы также можем просто зависеть от ApplicationContext, если это лучше подходит для нашей ситуации: что класс в основном для внутреннего использования.
ApplicationContext context;
public Resource loadEmployeesWithApplicationContext() {
return context.getResource("classpath:data/employees.dat");
}
Если мы видим использование ResourceUtils в нашем коде:
Мы должны тщательно обдумать обоснование, поскольку, вероятно, лучше использовать один из стандартных подходов, описанных выше.
4. Чтение данных ресурса
public File loadEmployeesWithSpringInternalClass()
throws FileNotFoundException {
return ResourceUtils.getFile(
"classpath:data/employees.dat");
}
Когда у нас есть ресурс, нам легко прочитать его содержимое. Как мы уже обсуждали, мы можем легко получить ссылку на файл или входной поток из ресурса.
Предположим, у нас есть следующий файл data/employees.dat в пути к классам:
4.1. Чтение в виде файла
Теперь мы можем прочитать его содержимое, вызвав getFile:
Joe Employee,Jan Employee,James T. Employee
Хотя следует отметить, что этот подход предполагает присутствие ресурса в файловой системе, а не в файле jar.
4.2. Чтение как InputStream
@Test
public void whenResourceAsFile_thenReadSuccessful()
throws IOException {
File resource = new ClassPathResource(
"data/employees.dat").getFile();
String employees = new String(
Files.readAllBytes(resource.toPath()));
assertEquals(
"Joe Employee,Jan Employee,James T. Employee",
employees);
}
Предположим, однако, что наш ресурс находится внутри jar.
Тогда мы можем вместо этого прочитать Resource как InputStream:
5. Заключение
В этой краткой статье мы рассмотрели несколько способов доступа и чтения ресурса из пути к классам с помощью Spring. Это включает активную и ленивую загрузку, а также файловую систему или банку.
@Test
public void whenResourceAsStream_thenReadSuccessful()
throws IOException {
InputStream resource = new ClassPathResource(
"data/employees.dat").getInputStream();
try ( BufferedReader reader = new BufferedReader(
new InputStreamReader(resource)) ) {
String employees = reader.lines()
.collect(Collectors.joining("\n"));
assertEquals("Joe Employee,Jan Employee,James T. Employee", employees);
}
}
Как всегда, все эти примеры доступны на GitHub.
«
As always, all of these examples are available over on GitHub.