1. Обзор
В этой статье мы обсудим Spring org.springframework.beans.factory.BeanDefinitionStoreException
— обычно за это отвечает BeanFactory
, когда определение bean-компонента недействительно, загрузка этого bean-компонента проблематична. В статье будут обсуждаться наиболее распространенные причины этого исключения, а также решения для каждой из них.
2. Причина: java.io.FileNotFoundException
Существует несколько возможных причин того, что BeanDefinitionStoreException
может быть вызвано базовым IOException
:
2.1. IOException
Разбор XML-документа из ресурса ServletContext
Обычно это происходит в веб-приложении Spring, когда DispatcherServlet
настроен в файле web.xml
для Spring MVC:
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
По умолчанию Spring будет искать файл с именем springMvcServlet-servlet.xml
в каталоге /WEB-INF
веб-приложения.
Если этот файл не существует, будет выдано следующее исключение:
org.springframework.beans.factory.BeanDefinitionStoreException:
Ioexception Parsing Xml Document from Servletcontext Resource [/WEB-INF/mvc-servlet.xml];
nested exception is java.io.FileNotFoundException:
Could not open ServletContext resource [/WEB-INF/mvc-servlet.xml]
Решение , конечно , состоит в том, чтобы убедиться, что файл mvc-servlet.xml
действительно существует в каталоге /WEB-INF
; если нет, то можно создать образец:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd" >
</beans>
2.2. IOException
Разбор XML-документа из ресурса пути к классу
Обычно это происходит, когда что-то в приложении указывает на несуществующий XML-ресурс или размещен не там, где должен быть.
Указание на такой ресурс может происходить различными способами.
Используя, например, конфигурацию Java, это может выглядеть так:
@Configuration
@ImportResource("beans.xml")
public class SpringConfig {...}
В XML это будет:
<import resource="beans.xml"/>
Или даже создав контекст Spring XML вручную:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Все это приведет к тому же исключению, если файл не существует:
org.springframework.beans.factory.BeanDefinitionStoreException:
Ioexception Parsing Xml Document from Servletcontext Resource [/beans.xml];
nested exception is java.io.FileNotFoundException:
Could not open ServletContext resource [/beans.xml]
Решение состоит в том , чтобы создать файл и поместить его в каталог /src/main/resources
проекта — таким образом, файл будет существовать в пути к классам, и он будет найден и использован Spring.
3. Причина: не удалось разрешить заполнитель…
Эта ошибка возникает, когда Spring пытается разрешить свойство, но не может — по одной из многих возможных причин.
Но сначала об использовании свойства — его можно использовать в XML:
... value="${some.property}" ...
Свойство также можно использовать в коде Java:
@Value("${some.property}")
private String someProperty;
Первое, что нужно проверить, это то, что имя свойства действительно соответствует определению свойства; в этом примере нам нужно определить следующее свойство:
some.property=someValue
Затем нам нужно проверить, где файл свойств определен в Spring — это подробно описано в моем руководстве по свойствам с помощью Spring . Хорошей практикой является размещение всех файлов свойств в каталоге /src/main/resources
приложения и их загрузка через:
"classpath:app.properties"
Переходим от очевидного — еще одна возможная причина того, что Spring не может разрешить свойство, заключается в том, что в контексте Spring может быть несколько bean -компонентов PropertyPlaceholderConfigurer
(или несколько элементов -заполнителей свойств )
Если это так, то решение состоит в том, чтобы либо свернуть их в один, либо настроить один в родительском контексте с ignoreUnresolvablePlaceholders
.
4. Причина: java.lang.NoSuchMethodError
Эта ошибка встречается в различных формах, одна из наиболее распространенных:
org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/mvc-servlet.xml];
nested exception is java.lang.NoSuchMethodError:
org.springframework.beans.MutablePropertyValues.add (Ljava/lang/String;Ljava/lang/Object;)
Lorg/springframework/beans/MutablePropertyValues;
Обычно это происходит, когда в пути к классам есть несколько версий Spring. Наличие более старой версии Spring случайно в пути к классам проекта встречается чаще, чем можно было бы подумать — я описал проблему и решение для этого в статье Spring Security with Maven .
Короче говоря, решение этой ошибки простое — проверьте все jar-файлы Spring в пути к классам и убедитесь, что все они имеют одинаковую версию — и эта версия 3.0 или выше.
Точно так же исключение не ограничивается bean-компонентом MutablePropertyValues
— есть несколько других воплощений той же проблемы, вызванных тем же несоответствием версии:
org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from class path resource [/WEB-INF/mvc-servlet.xml];
- nested exception is java.lang.NoSuchMethodError:
org.springframework.util.ReflectionUtils.makeAccessible(Ljava/lang/reflect/Constructor;)V
5. Причина: java.lang.NoClassDefFoundError
Распространенная проблема, аналогично связанная с Maven и существующими зависимостями Spring:
org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/mvc-servlet.xml];
nested exception is java.lang.NoClassDefFoundError:
org/springframework/transaction/interceptor/TransactionInterceptor
Это происходит, когда функциональность транзакций настроена в конфигурации XML:
<tx:annotation-driven/>
NoClassDefFoundError означает, что поддержка транзакций Spring, а именно spring
-tx
, не существует в пути к классам.
Решение простое — нужно определить spring-tx в Maven pom:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
Конечно, это не ограничивается функционалом транзакций — аналогичная ошибка выдается и при отсутствии AOP:
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException:
Unexpected exception parsing XML document from class path resource [/WEB-INF/mvc-servlet.xml];
nested exception is java.lang.NoClassDefFoundError:
org/aopalliance/aop/Advice
Теперь требуются следующие jar-файлы: spring-aop
(и неявно aopalliance
):
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.0.RELEASE</version>
</dependency>
6. Заключение
В конце этой статьи у нас должна быть четкая карта для навигации по множеству причин и проблем, которые могут привести к исключению хранилища определений компонентов
, а также хорошее понимание того, как исправить все эти проблемы.
Реализацию некоторых из этих примеров исключений можно найти в проекте github — это проект, основанный на Eclipse, поэтому его должно быть легко импортировать и запускать как есть.