Заредете ресурс като низ през пролетта

1. Общ преглед

В този урок ще разгледаме различни начини за впръскване на съдържанието на ресурс, съдържащ текст като String, в нашите пролетни зърна .

Ще разгледаме намирането на ресурса и ще прочетем съдържанието му.

Също така ще демонстрираме как да споделяме заредените ресурси в няколко зърна. Ще покажем това чрез използването на анотации, свързани с инжектирането на зависимости, въпреки че същото може да се постигне и чрез използване на XML-базирано инжектиране и деклариране на зърната в XML файла със свойства.

2. Използване на ресурс

Можем да опростим намирането на файл с ресурси, като използваме интерфейса на ресурса . Spring ни помага да намерим и прочетем ресурс с помощта на инструмента за зареждане на ресурси, който решава коя реализация на ресурса да избере в зависимост от предоставения път. В ресурс е ефективно средство за достъп до съдържанието на ресурса, а не самото съдържание.

Нека да видим някои начини за придобиване на екземпляр Resource за ресурси по пътя на класа.

2.1. Използване на ResourceLoader

Можем да използваме класа ResourceLoader, ако предпочитаме да използваме мързеливо зареждане:

ResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource("classpath:resource.txt");

Също така можем да инжектираме ResourceLoader в нашия боб с @Autowired :

@Autowired private ResourceLoader resourceLoader;

2.2 Използване на @Resource

Можем да инжектираме ресурс директно в Spring bean с @Value :

@Value("classpath:resource.txt") private Resource resource;

3. Преобразуване от ресурс в низ

След като имаме достъп до Ресурса , трябва да можем да го прочетем в низ . Нека създадем клас помощна програма ResourceReader със статичен метод asString, за да направим това за нас.

Първо, трябва да придобием InputStream :

InputStream inputStream = resource.getInputStream();

Следващата ни стъпка е да вземем този InputStream и да го преобразуваме в низ . Можем да използваме собствения метод на FileCopyUtils # copyToString на Spring :

public class ResourceReader { public static String asString(Resource resource) { try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) { return FileCopyUtils.copyToString(reader); } catch (IOException e) { throw new UncheckedIOException(e); } } // more utility methods }

Има много други начини за постигане на това, например, като се използват copyToString на пролетта на StreamUtils клас

Нека също така да създадете друг полезен метод readFileToString, който ще извлече ресурс за път, и се обадете на asString начин да го превърнете в String .

public static String readFileToString(String path) { ResourceLoader resourceLoader = new DefaultResourceLoader(); Resource resource = resourceLoader.getResource(path); return asString(resource); }

4. Добавяне на клас на конфигурация

Ако всеки боб трябваше да инжектира ресурс String s поотделно, има шанс както за дублиране на код, така и за по-голямо използване на паметта от зърната, като има свое собствено копие на String .

Можем да постигнем по-чисто решение, като инжектираме съдържанието на ресурса в един или няколко Spring фасула при зареждане на контекста на приложението. По този начин можем да скрием подробностите за изпълнението за четене на ресурса от различните компоненти, които трябва да използват това съдържание.

@Configuration public class LoadResourceConfig { // Bean Declarations }

4.1. Използване на боб, задържащ низ от ресурси

Нека декларираме боб, който да съдържа съдържанието на ресурса в клас @Configuration :

@Bean public String resourceString() { return ResourceReader.readFileToString("resource.txt"); }

Нека сега инжектираме регистрираните зърна в полетата, като добавим @Autowired анотация:

public class LoadResourceAsStringIntegrationTest { private static final String EXPECTED_RESOURCE_VALUE = "..."; // The string value of the file content @Autowired @Qualifier("resourceString") private String resourceString; @Test public void givenUsingResourceStringBean_whenConvertingAResourceToAString_thenCorrect() { assertEquals(EXPECTED_RESOURCE_VALUE, resourceString); } }

В този случай използваме анотацията @Qualifier и името на боб, тъй като може да се наложи да инжектираме няколко полета от един и същи тип - String .

Трябва да отбележим, че името на боб, използвано в квалификатора, е получено от името на метода, който създава боб в конфигурационния клас.

5. Използване на SpEL

И накрая, нека видим как можем да използваме Spring Expression Language, за да опишем кода, необходим за зареждане на ресурсен файл директно в поле в нашия клас.

Нека използваме анотацията @Value, за да инжектираме съдържанието на файла в полето resourceStringUsingSpel :

public class LoadResourceAsStringIntegrationTest { private static final String EXPECTED_RESOURCE_VALUE = "..."; // The string value of the file content @Value( "#{T(com.baeldung.loadresourceasstring.ResourceReader).readFileToString('classpath:resource.txt')}" ) private String resourceStringUsingSpel; @Test public void givenUsingSpel_whenConvertingAResourceToAString_thenCorrect() { assertEquals(EXPECTED_RESOURCE_VALUE, resourceStringUsingSpel); } }

Тук сме извикали ResourceReader # readFileToString, описвайки местоположението на файла, като използваме “classpath:” - префиксиран път в нашата анотация @Value .

За да намалим количеството код в SpEL, създадохме помощен метод в класа ResourceReader, който използва Apache Commons FileUtils за достъп до файла от предоставения път:

public class ResourceReader { public static String readFileToString(String path) throws IOException { return FileUtils.readFileToString(ResourceUtils.getFile(path), StandardCharsets.UTF_8); } }

6. Заключение

В този урок разгледахме някои от начините за конвертиране на ресурс в низ .

На първо място видяхме как да създадем ресурс за достъп до файла и как да четем от ресурс към низ.

След това показахме и как да скрием изпълнението на зареждането на ресурсите и да позволим съдържанието на низовете да се споделя в боб чрез създаване на квалифицирани зърна в @Configuration , позволявайки низовете да се свързват автоматично.

И накрая, използвахме SpEL, който осигурява компактно и незабавно решение, макар че изискваше персонализирана помощна функция, за да го спре да става твърде сложен.

Както винаги, кодът за примерите може да бъде намерен в GitHub