Эта статья участвовала в третьем этапе курса «High Yield Update» тренировочного лагеря для создателей Nuggets. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.
Spring определяет интерфейс Resource для доступа к ресурсам.Вообще говоря, ресурсы имеют две формы: одна предназначена для загрузки по внешним ссылкам в виде URL-адреса, а другая — для поиска из самой системы в форме файла.
Ресурс Spring предоставляет следующие интерфейсы:
public interface Resource extends InputStreamSource {
boolean exists();
boolean isOpen();
URL getURL() throws IOException;
File getFile() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
Resource наследует интерфейс InputStreamSource, и его определение приведено ниже:
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Встроенная реализация ресурсов
Spring имеет следующие встроенные реализации ресурсов:
- UrlResource
- ClassPathResource
- FileSystemResource
- ServletContextResource
- InputStreamResource
- ByteArrayResource
UrlResource
Urlresource inkapsulates java.net.url и может быть использован для доступа к любому объекту, обычно доступным через URL-адрес, такой как файлы, цели HTTP, целевые цели FTP и другие. Все URL-адреса могут использовать стандартизированный префикс для представления типа URL. Например: Файл: используется для доступа к пути файловой системы. http: используется для доступа к ресурсам через протокол HTTP. FTP: используется для доступа к ресурсам через FTP.
ClassPathResource
Он будет загружать ресурсы из пути к классам. Если в путь к ресурсу вывести префикс ClassPath:, то неявно разрешается в ClassPathResource.
Обратите внимание, что если файл ресурсов класса находится в файловой системе, реализация ресурса будет проанализирована как java.io.File, если он находится в пакете Jar, он будет проанализирован с использованием java.net.URL.
FileSystemResource
Это реализация ресурсов java.io.File и java.nio.file.Path, которая поддерживает синтаксический анализ в файл или URL.
ServletContextResource
Это реализация Resource ServletContext, которая интерпретирует относительные пути в корневом каталоге соответствующего веб-приложения.
InputStreamResource
InputStreamResource — это реализация InputStream Resource. Рассмотрите возможность его использования только в том случае, если другие реализации ресурсов недоступны.
В отличие от других реализаций Resource, это дескриптор уже открытого ресурса, поэтому isOpen() вернет true. Если вы хотите сохранить дескрипторы ресурсов или прочитать поток несколько раз, не используйте его.
ByteArrayResource
Является реализацией Resource массива байтов, который создает ByteArrayInputStream.
Это полезно для загрузки содержимого из любого заданного массива байтов без необходимости прибегать к одноразовому InputStreamResource.
ResourceLoader
ResourceLoader используется для возврата экземпляра Resource, вот его определение:
public interface ResourceLoader {
Resource getResource(String location);
}
Все контексты приложения реализуют класс ResourceLoader. Таким образом, все контексты приложения могут быть использованы для получения Resource.
Когда getResource() вызывается для определенного контекста приложения, а указанный путь местоположения не имеет определенного префикса, возвращается тип ресурса, соответствующий этому конкретному контексту приложения. Например, предположим, что следующий фрагмент кода выполняется для экземпляра ClassPathXmlApplicationContext:
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
В ClassPathXmlApplicationContext этот метод возвращает ClassPathResource, если в FileSystemXmlApplicationContext метод возвращает FileSystemResource. В WebApplicationContext метод возвращает ServletContextResource. Он вернет реализацию Resource, соответствующую ApplicationContext.
Конечно, вы можете принудительно использовать ClassPathResource независимо от ApplicationContext. Для этого вам нужно добавить префикс classpath:. следующее:
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
Точно так же вы можете принудительно использовать UrlResource, добавив стандартный префикс java.net.URL.
Resource template = ctx.getResource("file:///some/resource/path/myTemplate.txt");
Resource template = ctx.getResource("https://myhost.com/resource/path/myTemplate.txt");
ResourceLoaderAware
Интерфейс ResourceLoaderAware представляет собой специальный обратный вызов, указывающий, что компоненты, необходимые для предоставления ссылок ResourceLoader. Вот определение ResourceLoaderAware:
public interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader resourceLoader);
}
Когда класс реализует ResourceLoaderAware и развертывается в контексте приложения, весь класс идентифицируется как ResourceLoaderAware. Контекст приложения вызовет метод setResourceLoader(ResourceLoader) и передаст себя в качестве параметра (все контексты приложений Spring реализуют интерфейс ResourceLoader).
В компонентах приложения вы также можете использовать автозагрузку ResourceLoader вместо использования интерфейса ResourceLoaderAware. Вы можете использовать традиционный конструктор или режим автозагрузки byType. Или используйте аннотации.
ресурсы как зависимости
Если вы хотите внедрить статические ресурсы в bean-компоненты, вы можете просто преобразовать путь String в объект Resource. Если bean-компонент определяет свойство шаблона типа Resource, то ниже приведен очень простой пример конфигурации ресурса:
@Data
public class BeanA {
private Resource template;
}
<bean id="myBean" class="com.flydean.beans.BeanA">
<property name="template" value="bean.properties"/>
</bean>
Создать ClassPathXmlApplicationContext — Ярлык
ClassPathXmlApplicationContext предоставляет ярлык для поиска пути к ресурсу, который необходимо загрузить.
Просто предоставьте массив строк, который содержит только имя файла XML (без ведущей информации о пути) и класс. Затем ClassPathXmlApplicationContext получает информацию о пути из предоставленного класса.
следующее:
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
new String[] {"beanA.xml"}, BeanA.class);
}
Вот файловая структура:
com/
flydean/
beans/
beanA.xml
BeanA.class
подстановочные знаки пути к ресурсу
Ant-style Patterns
Пути к ресурсам можно определять с помощью шаблонов в стиле Ant. Ниже приведены примеры путей для шаблонов в стиле Ant.
/WEB-INF/*-context.xml
com/mycompany/**/applicationContext.xml
file:C:/some/path/*-context.xml
classpath:com/mycompany/**/applicationContext.xml
classpath: префикс*
Чтобы создать контекст приложения на основе XML, адрес пути может иметь префикс classpath*: следующим образом:
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
В чем разница между classpath* и classpath?
classpath* будет искать все подходящие пути к классам, а classpath найдет только первый соответствующий ресурс.
Соображения о ресурсах файловой системы
FileSystemResource, который не подключен к FileSystemApplicationContext (т. е. когда FileSystemApplicationContext не является фактическим ResourceLoader), обрабатывает абсолютные и относительные пути, как и ожидалось. Относительные пути относятся к текущему рабочему каталогу, а абсолютные пути — к корневому каталогу файловой системы.
Однако по соображениям обратной совместимости (историческим) это меняется, когда FileSystemApplicationContext является ResourceLoader. FileSystemApplicationContext заставляет все присоединенные экземпляры FileSystemResource рассматривать все пути расположения как относительные, независимо от того, начинаются ли они с косой черты. На практике это означает, что следующие примеры эквивалентны:
ApplicationContext ctx =
new FileSystemXmlApplicationContext("conf/context.xml");
ApplicationContext ctx =
new FileSystemXmlApplicationContext("/conf/context.xml");
На практике, если вам нужен истинный абсолютный путь к файловой системе, вам следует избегать использования абсолютных путей с FileSystemResource или FileSystemXmlApplicationContext и принудительно использовать UrlResource, используя префикс URL-адреса file:. В следующем примере показано, как это сделать:
// actual context type doesn't matter, the Resource will always be UrlResource
ctx.getResource("file:///some/resource/path/myTemplate.txt");
// force this FileSystemXmlApplicationContext to load its definition via a UrlResource
ApplicationContext ctx =
new FileSystemXmlApplicationContext("file:///conf/context.xml");
Примеры в этом разделе могут относиться кresources
Дополнительные руководства см.блог флайдина