Автор оригинала: Eugen Paraschiv.
1. Обзор
В этой статье мы обсуждаем Spring org.springframework.beans.factory.BeanCreationException – это очень распространенное исключение, возникающее, когда BeanFactory создает бобы определений бобов и сталкивается с проблемой. В статье будут рассмотрены наиболее распространенные причины этого исключения вместе с решением.
Дальнейшее чтение:
Введение в инверсию управления и инъекции зависимостей с помощью пружины
Интерфейсы BeanNameAware и BeanFactoryAware весной
Весна 5 Функциональная Регистрация Бобов
2. Причина: org.springframework.beans.factory.Исключение NoSuchBeanDefinitionException
На сегодняшний день наиболее распространенной причиной исключения BeanCreationException является попытка Spring ввести компонент, который не существует в контексте.
Например, Beans пытается ввести Bean :
@Component public class BeanA { @Autowired private BeanB dependency; ... }
Если a Bean B не найден в контексте, то будет выдано следующее исключение (ошибка создания Bean):
Error creating bean with name 'beanA': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.baeldung.web.BeanB cpm.baeldung.web.BeanA.dependency; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.baeldung.web.BeanB] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Чтобы диагностировать этот тип проблемы, сначала убедитесь, что компонент объявлен:
- либо в файле конфигурации XML с использованием элемента /> />
- или в классе Java @Configuration через аннотацию @Bean
- или аннотируется: @Component , @Repository , @Service , @Controller
Также убедитесь, что файлы конфигурации или классы действительно подобраны Spring и загружены в основной контекст.
Дальнейшее чтение:
Введение в инверсию управления и инъекции зависимостей с помощью пружины
Интерфейсы BeanNameAware и BeanFactoryAware весной
Весна 5 Функциональная Регистрация Бобов
3. Причина: org.springframework.beans.factory.Исключение NoUniqueBeanDefinitionException
Другой аналогичной причиной исключения создания компонента является попытка Spring ввести компонент по типу, а именно по его интерфейсу, и найти два или более компонента, реализующих этот интерфейс в контексте.
Например, BeanB1 и BeanB2 реализуют один и тот же интерфейс:
@Component public class BeanB1 implements IBeanB { ... } @Component public class BeanB2 implements IBeanB { ... } @Component public class BeanA { @Autowired private IBeanB dependency; ... }
Это приведет к следующему исключению, создаваемому фабрикой Spring bean:
Error creating bean with name 'beanA': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.baeldung.web.IBeanB com.baeldung.web.BeanA.b; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.baeldung.web.IBeanB] is defined: expected single matching bean but found 2: beanB1,beanB2
4. Причина: org.springframework.beans.Исключение BeanInstantiationException
4.1. Пользовательское исключение
Следующим в строке является компонент, который создает исключение в процессе его создания ; упрощенный пример, чтобы легко проиллюстрировать и понять проблему, создает исключение в конструкторе компонента:
@Component public class BeanA { public BeanA() { super(); throw new NullPointerException(); } ... }
Как и ожидалось, это приведет к быстрому сбою весны со следующим исключением:
Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: Constructor threw exception; nested exception is java.lang.NullPointerException
4.2. java.lang.Исключение InstantiationException
Еще одним возможным случаем исключения BeanInstantiationException является определение абстрактного класса в качестве компонента в XML; это должно быть в XML, потому что нет способа сделать это в файле конфигурации Java @, и сканирование пути к классу будет игнорировать абстрактный класс:
@Component public abstract class BeanA implements IBeanA { ... }
И XML-определение компонента:
Эта настройка приведет к аналогичному исключению:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanA' defined in class path resource [beansInXml.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: Is it an abstract class?; nested exception is java.lang.InstantiationException
4.3. java.lang.Исключение noSuchMethod
Если у компонента нет конструктора по умолчанию, и Spring пытается создать его экземпляр, ища этот конструктор, это приведет к исключению во время выполнения; например:
@Component public class BeanA implements IBeanA { public BeanA(final String name) { super(); System.out.println(name); } }
Когда этот компонент будет обнаружен механизмом сканирования пути к классам, произойдет сбой:
Error creating bean with name 'beanA' defined in file [...BeanA.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.baeldung.web.BeanA]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.baeldung.web.BeanA.()
Аналогичное исключение, но более трудное для диагностики, может возникнуть, когда зависимости Spring от пути к классу не имеют той же версии ; такого рода несовместимость версий может привести к исключению noSuchMethod из-за изменений API. Решение такой проблемы заключается в том, чтобы убедиться, что все библиотеки Spring имеют одну и ту же версию в проекте.
5. Причина: org.springframework.beans.Исключение NotWritablePropertyException
Еще одна возможность заключается в определении боба – BeanA – со ссылкой на другой боб – BeanB – без соответствующего метода сеттера в BeanA :
@Component public class BeanA { private IBeanB dependency; ... } @Component public class BeanB implements IBeanB { ... }
И конфигурация Spring XML:
Опять же, это может произойти только в конфигурации XML , потому что при использовании Java @Configuration компилятор сделает эту проблему невозможной для воспроизведения.
Конечно, для того, чтобы решить эту проблему, сеттер должен быть добавлен для IBeanB :
@Component public class BeanA { private IBeanB dependency; public void setDependency(final IBeanB dependency) { this.dependency = dependency; } }
6. Причина: org.springframework.beans.factory.Исключение CannotLoadBeanClassException
Это исключение возникает, когда Spring не может загрузить класс определенного компонента – это может произойти, если конфигурация Spring XML содержит компонент, который просто не имеет соответствующего класса. Например, если класс Benz не существует, следующее определение приведет к исключению:
Основная причина, если исключение ClassNotFoundException и полное исключение в этом случае:
nested exception is org.springframework.beans.factory.BeanCreationException: ... nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.baeldung.web.BeanZ] for bean with name 'beanZ' defined in class path resource [beansInXml.xml]; nested exception is java.lang.ClassNotFoundException: com.baeldung.web.BeanZ
7. Дети BeanCreationException
7.1. Организация. springframework.beans.factory.BeanCurrentlyInCreationException
Одним из подклассов BeanCreationException является BeanCurrentlyInCreationException ; обычно это происходит при использовании инъекции конструктора – например, в случае циклических зависимостей:
@Component public class BeanA implements IBeanA { private IBeanB beanB; @Autowired public BeanA(final IBeanB beanB) { super(); this.beanB = beanB; } } @Component public class BeanB implements IBeanB { final IBeanA beanA; @Autowired public BeanB(final IBeanA beanA) { super(); this.beanA = beanA; } }
Весна не сможет разрешить такой сценарий проводки, и конечный результат будет:
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
Полное исключение очень многословно:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanA' defined in file [...BeanA.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanB]: : Error creating bean with name 'beanB' defined in file [...BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'beanB' defined in file [...BeanB.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.baeldung.web.IBeanA]: : Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
7.2. Организация.springframework.beans.factory.BeanIsAbstractException
Это исключение создания экземпляра может возникнуть, когда BeanFactory пытается получить и создать экземпляр компонента, который был объявлен как абстрактный; например:
public abstract class BeanA implements IBeanA { ... }
Объявлено в конфигурации XML как:
Теперь, если мы попытаемся извлечь Бобы из контекста Spring по имени – например, при создании экземпляра другого боба:
@Configuration public class Config { @Autowired BeanFactory beanFactory; @Bean public BeanB beanB() { beanFactory.getBean("beanA"); return new BeanB(); } }
Это приведет к следующему исключению:
org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'beanA': Bean definition is abstract
И полная трассировка стека исключений:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanB' defined in class path resource [org/baeldung/spring/config/WebConfig.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public com.baeldung.web.BeanB com.baeldung.spring.config.WebConfig.beanB()] threw exception; nested exception is org.springframework.beans.factory.BeanIsAbstractException: Error creating bean with name 'beanA': Bean definition is abstract
8. Заключение
В конце этой статьи у нас должна быть четкая карта для навигации по множеству причин и проблем, которые могут привести к BeanCreationException весной, а также хорошее представление о том, как исправить все эти проблемы.
Примеры реализации всех исключений можно найти в проекте github – это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.