Classpathxmlapplicationcontext где ищет файл

Обновлено: 02.07.2024

Простое использование класса ClassPathXmlApplicationContext в Spring и простой случай весны

Во-первых, просто используйте ApplicationContext в качестве теста для получения экземпляра (объекта) Bean, определенного в Spring. Вы можете использовать:

ApplicationContext ac = new ClassPathXmlApplicationContext(“applicationContext.xml”);
RegisterDAO registerDAO = (RegisterDAO)ac.getBean(“RegisterDAO”);

Если их больше двух:
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]);

Или используйте подстановочные знаки:
ApplicationContext ac = new ClassPathXmlApplicationContext(“classpath:/*.xml”);

Во-вторых, разница между ClassPathXmlApplicationContext [может читать только файлы конфигурации, размещенные в каталоге web-info / classes] и FileSystemXmlApplicationContext

classpath: префикс не нужен, по умолчанию он находится ниже пути к classpath проекта;
Если вы хотите использовать абсолютный путь, вам нужно добавить префикс file:, чтобы указать, что это абсолютный путь;

Для FileSystemXmlApplicationContext:
По умолчанию существует два типа:

1. То, что не имеет буквы диска, - это рабочий путь проекта, то есть корневой каталог проекта;
2. Буква диска указывает абсолютный путь к файлу.

Если вы хотите использовать путь к classpath, вам нужно добавить префикс classpath:

public class HelloClient

protected static final Log log = LogFactory.getLog(HelloClient.class);

public static void main(String[] args) // Resource resource = new ClassPathResource(“appcontext.xml”);
// BeanFactory factory = new XmlBeanFactory(resource);

Ниже приведен небольшой пример моего теста жизненного цикла бина:
Позвольте мне рассказать о принципе этого небольшого весеннего случая, он может быть полезен для студентов, которые только начинают изучать весну. В конце концов, я только недавно узнал.
Это фактически для того, чтобы сначала создать файл интерфейса CustomerDAO.java, записать абстрактный метод в файл, а затем реализовать файл класса интерфейса в CustomerDAOImpl.java, который должен поместить Все методы переписаны, и могут быть написаны некоторые другие методы. Файл конфигурации приложения applicationContext.xml на самом деле является более важным управлением в режиме фабрики пружин. После записи тега компонента идентификатор устанавливается самостоятельно, чтобы Getbean ("id name"), записанное в тестовом классе, на самом деле является именем, которое мы сами задаем в скобках. Тогда этот случай предназначен для тестирования жизненного цикла компонента, поэтому напишите метод init и Атрибут destroy-method является фактически началом и исчезновением жизни bean-компонента. Значение атрибута - это имя метода, которое мы хотим записать в классе реализации. Первая строка в тестовом файле Spring Spring Demo2 ApplicationContext applicationContext = new ClassPathXmlApplicationContext ("applicationContext.xml") На самом деле, это получить файл XML, который был создан в это время Объект.
1. Файл интерфейса CustomerDAO.java:


2. CustomerDAOImpl.java реализует файл класса интерфейса:

3. Файл конфигурации Spring файла applicationContext.xml:

4. Испытательный файл Spring в SpringDemo2:

Пару месяцев назад в моем профиле был опубликован подробный пост по загрузке классов на JVM. После этого доклада мои коллеги задались хорошим вопросом: а какой механизм использует Spring для разбора конфигураций и как он загружает классы из контекста?



После многих часов дебага спринговых исходников мой коллега экспериментальным путём докопался до той самой простой и понятной правды.

Немного теории

Сразу определим, что ApplicationContext — это главный интерфейс в Spring-приложении, который предоставляет информацию о конфигурации приложения.

Перед тем, как перейти непосредственно к демонстрации, взглянем на этапы формирования ApplicationContext:


В этом посте разберем первый этап, так как нас интересует именно чтение конфигураций и создание BeanDefinition.

BeanDefinition — это интерфейс, который описывает бин, его свойства, аргументы конструктора и другую метаинформацию.

Что касается конфигурации самих бинов, у Spring есть 4 способа конфигурации:

  1. Xml конфигурация — ClassPathXmlApplicationContext(”context.xml”);
  2. Groovy конфигурация — GenericGroovyApplicationContext(”context.groovy”);
  3. Конфигурация через аннотации с указанием пакета для сканирования — AnnotationConfigApplicationContext(”package.name”);
  4. JavaConfig — конфигурация через аннотации с указанием класса (или массива классов) помеченного аннотацией @Configuration — AnnotationConfigApplicationContext(JavaConfig.class).

Xml конфигурация

За основу берем простой проект:


Здесь следует немного пояснить, какие методы и для чего используются:

  • printLoadedClasses(String… filters) — метод выводит в консоль название загрузчика и загруженных JVM классов из пакета, переданного как параметр. Дополнительно есть информация о количестве всех загруженных классов;
  • doSomething(Object o) — метод, который делает примитивную работу, но не позволяет исключить упомянутые классы в процессе оптимизации при компиляции.


В 25 строке идет объявление и инициализация ApplicationContext через конфигурацию Xml.

Конфигурационный Xml-файл выглядит следующим образом:


При конфигурации бина указываем реально существующий class. Обратите внимание на заданное свойство lazy-init=”true”: в этом случае бин будет создаваться только после запроса его из контекста.

Смотрим, как Spring при поднятии контекста разрулит ситуацию с классами, объявленными в конфигурационном файле:


Разберемся с деталями Xml конфигурации:

— Чтением файла конфигурации занимается класс XmlBeanDefinitionReader, который реализует интерфейс BeanDefinitionReader;

XmlBeanDefinitionReader на входе получает InputStream и загружает Document через DefaultDocumentLoader:


— После этого каждый элемент этого документа обрабатывается и, если он является бином, создается BeanDefinition на основе заполненных данных (id, name, class, alias, init- method, destroy-method и др.):


— Каждый BeanDefinition помещается в Map, который хранится в классе DefaultListableBeanFactory:


В коде Map выглядит следующим образом:


Теперь в том же конфигурационном файле добавим еще одно объявление бина с классом film.BadVillain:


Смотрим, что получится, если распечатать список созданных BeanDefenitionNames и загруженные классы:


Несмотря на то, что класса film.BadVillain, указанного в конфигурационном файле, не существует, Spring отрабатывает без ошибок:


Cписок BeanDefenitionNames содержит 2 элемента; то есть, те 2
BeanDefinition, сконфигурированные в нашем файле, были созданы.

Конфигурации обоих бинов, по сути, одинаковы. Но, при этом существующий класс загрузился, никаких проблем не возникло. Из чего можно сделать вывод, что попытка загрузить несуществующий класс также была, но провальная попытка ничего не сломала.

Попытаемся получить еще и сами бины по их именам:


Если в первом случае был получен валидный бин, то во втором случае прилетел exception.

Обратите внимание на stack trace: сработала отложенная загрузка классов. Выполняется обход всех загрузчиков классов в попытке найти искомый класс среди загруженных ранее. И после того, как нужный класс не был найден, с помощью вызова метода Utils.forName, происходит попытка найти несуществующий класс по имени, что привело к получению закономерной ошибки.

При поднятии контекста загрузился только один класс, при этом попытка загрузки несуществующего файла не привела к ошибке. Почему так произошло?

Всё потому, что мы прописали lazy-init:true и запретили Spring создавать экземпляр бина, где и генерируется полученный ранее exception. Если убрать это свойство из конфигурации либо изменить его значение lazy-init:false, то описанная выше ошибка также вылетит, но не будет проигнорирована и приложение остановиться. В нашем случае контекст был проинициализирован, но мы не смогли создать экземпляр бина, т.к. указанный класс не был найден.

Groovy конфигурация

При конфигурации контекста с помощью Groovy-файла, необходимо сформировать GenericGroovyApplicationContext, который принимает на вход строку с конфигурацией контекста. Чтением контекста в данном случае занимается класс GroovyBeanDefinitionReader. Эта конфигурация работает по сути так же, как и Xml, только с Groovy-файлами. К тому же, GroovyApplicationContext нормально работает и с Xml-файлом.

Пример простого конфигурационного Groovy-файла:


Пробуем проделать то же самое, что и с Xml:


Ошибка вылетает сразу: Groovy так же, как и Xml, создает BeanDefenition'ы, но в данном случае постпроцессор сразу выдаёт ошибку.

Конфигурация через аннотации с указанием пакета для сканирования или JavaConfig

Данная конфигурация отличается от двух предыдущих. В конфигурация через аннотации используется 2 варианта: JavaConfig и аннотация над классами.

Здесь используется один и тот же контекст: AnnotationConfigApplicationContext(“package”/JavaConfig.class). Работает он в зависимости от того, что было передано в конструктор.

В контексте AnnotationConfigApplicationContext есть 2 приватных поля:

  • private final AnnotatedBeanDefinitionReader reader (работает с JavaConfig);
  • private final ClassPathBeanDefinitionScanner scanner (сканирует пакет).

Создаем конфигурационный файл с максимально простым бином. Смотрим, что загрузится:


Если в случае с Xml и Groovy загрузилось столько BeanDefinition, сколько было объявлено, то в данном случае в процессе поднятия контекста загружаются как объявленные, так и дополнительные BeanDefinition. В случае реализации через JavaConfig все классы загружаются сразу, в том числе и класс самого JavaConfig, так как он сам является бином.

Еще один момент: в случае с Xml и Groovy конфигурациями загрузилось 343 файла, здесь же произошла более “тяжелая” загрузка количеством 631 доп файл.

Этапы работы ClassPathBeanDefinitionScanner:

  • По указанному пакету определяется список файлов для сканирования. Все файлы попадают в директории;
  • Сканер проходит по каждому файлу, получает InputStream и сканирует при помощи класса org.springframework.asm.ClassReader.class;
  • На 3-ем этапе сканер проверяет, проходят ли найденные объекты по фильтрам аннотации org.springframework.core.type.filter.AnnotationTypeFilter. По умолчанию Spring ищет классы, которые помечены аннотацией Component либо любой другой аннотацией, которая включает в себя Component;
  • Если проверка проходит успешно, создаются и регистрируются новые BeanDefinition.

Рассмотрим работу сканера на простом примере.

Создаем собственную аннотацию для поиска соответствующих классов:


Создаем 2 класса: один со стандартной аннотацией Component, второй — с кастомной аннотацией:

В результате получаем сформированные BeanDefinition для этих классов и успешно загруженные классы.



Вывод

Из всего вышесказанного на поставленные вопросы можно ответить следующим образом:

Краткое руководство с введением в ClassPathXmlApplicationContext, которое охватывает API, жизненный цикл и интернационализацию с примерами.

1. Обзор

Ядро Spring Framework-это, проще говоря, контейнер IoC, используемый для управления бобами.

В Spring есть два основных типа контейнеров – фабрика бобов и Контекст приложения. Первый обеспечивает основные функциональные возможности, которые представлены здесь ; последний является надмножеством первого и наиболее широко используется.

В этой статье мы сосредоточимся на полезных функциях, предоставляемых ClassPathXmlApplicationContext .

2. Основное использование

2.1. Инициализация контейнера и управление бобами

ClassPathXmlApplicationContext может загружать конфигурацию XML из пути к классу и управлять ее компонентами:

У нас есть Студент класс:

Мы настраиваем Студент был в classpathxmlapplicationcontext-example.xml и добавьте его в путь к классу:

Теперь мы можем использовать ClassPathXmlApplicationContext для загрузки конфигурации XML и получения компонента Student :

2.2. Несколько конфигураций XML

Иногда мы хотим использовать несколько конфигураций XML для инициализации контейнера Spring. В этом случае нам просто нужно добавить несколько местоположений конфигурации при построении ApplicationContext :

3. Дополнительные Возможности

3.1. Изящно Закройте Пружинный контейнер МоК

Когда мы используем контейнер Spring IoC в веб-приложении, веб-реализации Spring ApplicationContext будут корректно завершать работу контейнера при закрытии приложения, но если мы используем его в не веб-среде, такой как автономное настольное приложение, мы должны самостоятельно зарегистрировать крюк завершения работы в JVM, чтобы убедиться, что контейнер Spring IoC корректно завершается и вызывает методы destroy для освобождения ресурсов.

Давайте добавим метод destroy() в класс Student :

Теперь мы можем настроить этот метод как метод уничтожения student bean:

Теперь мы зарегистрируем крюк выключения:

Когда мы запускаем метод тестирования, мы видим, что вызывается метод destroy () .

Интерфейс ApplicationContext расширяет интерфейс MessageSource , поэтому обеспечивает функциональность интернационализации.

Контейнер ApplicationContext автоматически выполняет поиск компонента MessageSource при его инициализации, и этот компонент должен быть назван как MessageSource .

Во-первых, давайте добавим каталог dialog в путь к классу и добавим два файла в каталог диалога: dialog_en.properties и dialog_zh_CN.properties .

Настройте MessageSource bean в classpathxmlapplicationcontext-internationalization.xml :

Затем давайте получим диалоговые слова разных языков с помощью MessageSource :

4. Ссылка на текст приложения

Иногда нам нужно получить ссылку на ApplicationContext внутри управляемых им компонентов, для этого мы можем использовать ApplicationContextAware или @Autowired . Давайте посмотрим, как работает ApplicationContextAware :

У нас есть Курс класс с именем:

У нас есть Учитель класс, который собирает свои курсы в соответствии с фасолью контейнера:

Давайте настроим курс боб и учитель был в classpathxmlapplicationcontext-example.xml :

Затем – протестируйте инъекцию курсов свойства:

Помимо реализации интерфейса ApplicationContextAware , использование аннотации @Autowired имеет тот же эффект.

Давайте изменим класс Учитель на этот:

Затем запустите этот тест, и мы увидим, что результат тот же.

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

ApplicationContext -это контейнер Spring с более специфичными для предприятия функциями по сравнению с BeanFactory , а ClassPathXmlApplicationContext является одной из его наиболее часто используемых реализаций.

Поэтому в этой статье мы представили несколько аспектов ClassPathXmlApplicationContext , включая его базовое использование , функциональность регистрации завершения работы, функциональность интернационализации и получение ссылки на него.

Я пытаюсь изучить фреймворк Spring, следуя этому учебнику:

Я должен создать новый проект Maven с помощью:

Это не веб-приложение. Я хочу создать простое приложение java, и мой основной метод заключается в следующем:

Если я не ошибаюсь, конструктор ClassPathXmlApplicationContext ищет файл в папке src/main/resources. Но когда я выполнил приложение, я получил исключение "файл не найден beans.xml". Я попробовал с полным маршрутом к файлу beans.xml src/main/resources/beans.xml и тоннами маршрутов.

Когда я использую этот код для проверки существования моего файла, он говорит, что существует.

Я ничего не понимаю. Какая-нибудь помощь, пожалуйста?

Еще одна вещь, которую я хотел бы спросить, - это нужно ли мне использовать xml для инъекции зависимостей. Могу ли я работать с фреймворком spring без использования определений XML?

Я видел аннотации типа @Autowired и многое другое, но я также не могу заставить их работать. Интересно, нужно ли мне использовать комбинацию аннотаций xml+.

2 ответа

У меня есть контекстный файл spring и файл свойств, расположенный в корне моего проекта. При запуске gradle distZip я получаю все включенные источники, а также библиотеки, но как я также включаю эти два файла?

Я использую Apache Tomcat 7, и это ON-Spring 3 со всеми библиотеками на classpath (компиляция и время выполнения). это мой файл web.xml в /WEB-INF/ web.xml : <context-param> <param-name>contextConfigLocation</param-name>.

Если вы поместите файл в корневой каталог вашего classpath (и это то, что вы делаете), используйте

для ссылки на него ("/" в начале).

ClassPathXmlApplicationContext не ищет файл в файле /src/main/resources. Он пытается найти его в classpath ("root" вашего файла jar).

Но все, что вы поместили в src/main/resources, будет помещено в "root" (в classpath so) maven, когда вы создадите свое приложение.

Похожие вопросы:

Учитывая, что контекстный файл Tomcat XML имеет тенденцию содержать конфиденциальную информацию (часто включая учетные данные, необходимые для подключения к базе данных), как я могу динамически.

Я хотел бы загрузить контекстный файл из файла jar. Например, я хочу создать файл доступа к данным jar - содержит сущность и объекты dao, и он будет иметь контекстный файл spring.

Я уже видел этот вопрос здесь раньше, но не смог разобраться в этом вопросе. Я использую spring в своем проекте Java, и файл xml, хотя он и существует, не может быть найден. INFO: Loading XML bean.

У меня есть контекстный файл spring и файл свойств, расположенный в корне моего проекта. При запуске gradle distZip я получаю все включенные источники, а также библиотеки, но как я также включаю эти.

Я использую Apache Tomcat 7, и это ON-Spring 3 со всеми библиотеками на classpath (компиляция и время выполнения). это мой файл web.xml в /WEB-INF/ web.xml : <context-param>.

Я хочу использовать spring для не-веб-проекта Java. Куда должен идти контекстный файл? Как определить их местоположение в контейнере Spring? Я уверен, что есть разные варианты , но с веб-приложением.

Я пытаюсь изучить фреймворк Spring. Я делаю простое тестовое приложение. У меня есть клиент, который вызывает службу, которая вызывает DAO. Клиент вызывает службу следующим образом: XML <bean.

Я создал приложение с помощью worklight 6.0. после сборки и развертывания откройте консоль, которую я получаю Контекстный Корень Не Найден Я проверил файл worklight.properties и добавил туда номер.

Я создал динамический веб-проект и добавил файл context.xml в папку META-INF , как упоминалось здесь . Но когда я развертываю файл war, контекстный файл не копируется в папку.

У меня есть приложение Spring Boot 2.0, которое я пытаюсь развернуть в виде файла WAR. Это означает, что он будет иметь пользовательский контекстный путь. Для тестирования в качестве приложения Java.

Spring_Deep_8.11-5020-366d55.jpg

Контекст (а у него есть даже интерфейс — org.springframework.context.ApplicationContext ) — это некоторое окружение, в котором работает приложение на Spring Framework. Страшные аббревиатуры DI, IoC — это всё про него. Собственно, контекст создаёт и хранит экземпляры классов вашего приложения, определяет их зависимости друг с другом и автоматически их задаёт.

Безусловно, для того чтобы Spring создал контекст с экземплярами классов, ему нужно предоставить дополнительную информацию — мета-данные, из каких классов/объектов состоит ваше приложение, как они создаются, какие у них есть зависимости и т. д.

Итого: Spring Context + мета-данные = работающее приложение.

Где найти контекст?

Контекст является ключевой функциональностью Spring и лежит в maven-зависимости spring-context (на момент написания — org.springframework:spring-context:5.1.4.RELEASE ). Обычно эта зависимость является транзитивной для остальных проектов Spring. И если вы, например, подключаете spring-boot-starter, то она подключится автоматически, и не нужно думать про то, где её взять.

Но если вы хотите попробовать "голый" Spring, т. е. только ту часть, которая называется IoC-контейнер, то достаточно подключить лишь spring-context.

Итого: подключите org.springframework:spring-context:5.1.4.RELEASE .

Какие бывают контексты и как их создать?

У интерфейса ApplicationContext есть большое количество реализаций: — ClassPathXmlApplicationContext ; — FileSystemXmlApplicationContext ; — GenericGroovyApplicationContext ; — AnnotationConfigApplicationContext ; — и даже StaticApplicationContext ; — а также некоторые другие.

Они отличаются друг от друга именно тем, каким способом задаются мета-данные и где хранится эта конфигурация. Например: — ClassPathXmlApplicationContext — метаданные конфигурируются XML-файлом(-ами) и они лежат в classpath, т. е. в ресурсах модуля; — FileSystemXmlApplicationContext — метаданные тоже конфигурируются XML-файлом(-ами), но они находятся где-то в файловой системе, например, /etc/yourapp/spring-context.xml ; — AnnotationConfigApplicationContext — метаданные конфигурируются с помощью аннотаций прямо на классах.

Современным способом конфигурирования считаются аннотации ( AnnotationConfigApplicationContext ), дальше будем создавать именно их.

Приведём пример создания такого контекста в методе main:

Внутри конструктора как раз и происходит инициализация контекста из мета-данных. Как и полагается, в AnnotationConfigApplicationContext мета-данные конфигурируются аннотациями. Несложно заметить аннотацию @Configuration на Main -классе, и что он передаётся в конструктор контекста. Собственно, Main и есть описание метаданных.

Итого: создаём контекст.

В результате мы получили работающее приложение на Spring. Правда, пока ещё без бизнес-логики. А что же означает аннотация @ComponentScan , и как правильно определять и писать бины, мы узнаем в следующей части.

Следите за новостями, оставляйте комментарии и посмотрите программу курса «Разработчик на Spring Framework», вдруг захочется погрузится полностью!

Читайте также: