Рубрики
Без рубрики

Весеннее BeanCreationException

Краткое и практическое руководство по устранению различных причин исключения весеннего BeanCreationException

Автор оригинала: 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, поэтому его должно быть легко импортировать и запускать как есть.