Spring BeanCreationException

Spring BeanCreationException

1. обзор

В этой статье мы обсуждаемSpring org.springframework.beans.factory.BeanCreationException - это очень распространенное исключение, возникающее, когдаBeanFactory создает bean-компоненты определений bean-компонентов и сталкивается с проблемой. В статье будут обсуждаться наиболее распространенные причины этого исключения, а также решение.

Дальнейшее чтение:

Введение в инверсию управления и инжекцию зависимостей с помощью пружины

Краткое введение в концепции инверсии управления и внедрения зависимостей с последующей простой демонстрацией с использованием Spring Framework

Read more

Интерфейсы BeanNameAware и BeanFactoryAware в Spring

Взгляните на работу с интерфейсами BeanNameAware и BeanFactoryAware в Spring.

Read more

Spring 5 Функциональная регистрация бобов

Посмотрите, как зарегистрировать бины с помощью функционального подхода в Spring 5.

Read more

2. Причина:org.springframework.beans.factory.NoSuchBeanDefinitionException

Безусловно, наиболее распространенной причинойBeanCreationException является попытка Spring выполнитьinject a bean that doesn’t exist в контексте.

Например,BeanA пытается ввестиBeanB:

@Component
public class BeanA {

    @Autowired
    private BeanB dependency;
    ...
}

ЕслиBeanB не найден в контексте, будет выброшено следующее исключение (Ошибка создания компонента):

Error creating bean with name 'beanA': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.example.web.BeanB org.example.web.BeanA.dependency;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.example.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 с использованием элемента<bean />

  • или в классе Java@Configuration через аннотацию@Bean

  • или аннотируется:@Component,@Repository,@Service,@Controller, и для этого пакета активно сканирование пути к классам

Также убедитесь, что файлы конфигурации или классы действительно выбраны Spring и загружены в основной контекст.

Дальнейшее чтение:

Введение в инверсию управления и инжекцию зависимостей с помощью пружины

Краткое введение в концепции инверсии управления и внедрения зависимостей с последующей простой демонстрацией с использованием Spring Framework

Read more

Интерфейсы BeanNameAware и BeanFactoryAware в Spring

Взгляните на работу с интерфейсами BeanNameAware и BeanFactoryAware в Spring.

Read more

Spring 5 Функциональная регистрация бобов

Посмотрите, как зарегистрировать бины с помощью функционального подхода в Spring 5.

Read more

3. Причина:org.springframework.beans.factory.NoUniqueBeanDefinitionException

Другой похожей причиной исключения создания bean-компонента является попытка Spring внедрить bean-компонент по типу, а именно по его интерфейсу, и поискtwo or more bean implementing that interface в контексте.

Например,BeanB1 иBeanB2 реализуют один и тот же интерфейс:

@Component
public class BeanB1 implements IBeanB { ... }
@Component
public class BeanB2 implements IBeanB { ... }

@Component
public class BeanA {

    @Autowired
    private IBeanB dependency;
    ...
}

Это приведет к тому, что фабрика bean-компонентов Spring выдаст следующее исключение:

Error creating bean with name 'beanA': Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: private org.example.web.IBeanB org.example.web.BeanA.b;
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [org.example.web.IBeanB] is defined:
expected single matching bean but found 2: beanB1,beanB2

4. Причина:org.springframework.beans.BeanInstantiationException

4.1. Пользовательское исключение

Следующим на очереди идетbean that throws an exception during its creation process; упрощенный пример, чтобы легко проиллюстрировать и понять проблему, вызывает исключение в конструкторе bean-компонента:

@Component
public class BeanA {

    public BeanA() {
        super();
        throw new NullPointerException();
    }
    ...
}

Как и следовало ожидать, это приведет к быстрому сбою Spring за следующим исключением:

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 [org.example.web.BeanA]:
Constructor threw exception;
nested exception is java.lang.NullPointerException

4.2. java.lang.InstantiationExceptionс

Другой возможный случайBeanInstantiationException - это определение абстрактного класса как bean-компонента в XML; это должно быть в XML, потому что это невозможно сделать в файле Java @Configuration, а сканирование пути к классам будет игнорировать абстрактный класс:

@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 [org.example.web.BeanA]:
Is it an abstract class?;
nested exception is java.lang.InstantiationException

4.3. java.lang.NoSuchMethodExceptionс

Если у bean-компонента нет конструктора по умолчанию, и 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 [org.example.web.BeanA]:
No default constructor found;
nested exception is java.lang.NoSuchMethodException: org.example.web.BeanA.()

Подобное исключение, но его труднее диагностировать, может возникнуть, когда зависимости Spring на пути к классам не имеютsame version; такая несовместимость версий может привести кNoSuchMethodException из-за изменений API. Решение такой проблемы - убедиться, что все библиотеки Spring имеют одинаковую версию в проекте.

5. Причина:org.springframework.beans.NotWritablePropertyException

Еще одна возможность - определить bean-компонент -BeanA - со ссылкой на другой bean-компонент -BeanB - без соответствующего метода установки вBeanA:

@Component
public class BeanA {
    private IBeanB dependency;
    ...
}
@Component
public class BeanB implements IBeanB { ... }

И конфигурация Spring XML:


    

Опять же, этоcan only occur in XML Configuration, потому что при использовании 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 cannot load the class of the defined bean - это может произойти, если конфигурация Spring XML содержит компонент, у которого просто нет соответствующего класса. Например, если классBeanZ не существует, следующее определение приведет к исключению:

Основная причинаClassNotFoundException и полного исключения в этом случае:

nested exception is org.springframework.beans.factory.BeanCreationException:
...
nested exception is org.springframework.beans.factory.CannotLoadBeanClassException:
Cannot find class [org.example.web.BeanZ] for bean with name 'beanZ'
defined in class path resource [beansInXml.xml];
nested exception is java.lang.ClassNotFoundException: org.example.web.BeanZ

7. ДетиBeanCreationException

7.1. org.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;
    }
}

Spring не сможет разрешить такой сценарий подключения, и конечным результатом будет:

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 [org.example.web.IBeanB]: :
Error creating bean with name 'beanB' defined in file [...BeanB.class]:
Unsatisfied dependency expressed through constructor argument with index 0
of type [org.example.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 [org.example.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. org.springframework.beans.factory.BeanIsAbstractException

Это исключение экземпляра может произойти, когда Фабрика Бинов пытается извлечь и создать экземпляр компонента, который был объявлен как абстрактный; например:

public abstract class BeanA implements IBeanA {
   ...
}

Объявлено в конфигурации XML как:

Теперь, если мы попытаемсяretrieve BeanA from the Spring Context by name - например, при создании экземпляра другого bean-компонента:

@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

И полное исключение stacktrace:

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'beanB' defined in class path resource
[org/example/spring/config/WebConfig.class]: Instantiation of bean failed;
nested exception is org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method
[public org.example.web.BeanB org.example.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 в Spring, а также хорошее представление о том, как исправить все эти проблемы.

Реализацию всех примеров исключений можно найти вthe github project - это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.