Tuesday, 21 August 2018

Causes and Solution of NoSuchBeanDefinitionException in Spring.

        In previous post, we discussed the cause and solution of LazyInitializationException  in Hibernate. In the current post, we will see the cause and solution of NoSuchBeanDefinitionException in Spring.

        In Spring there are so many exceptions NoSuchBeanDefinitionException,  NoUniqueBeanDefinitionException, BeanInstantiationException, CannotLoadBeanClassException and so on. But the most important and faced exception is NoSuchBeanDefinitionException.

        This  exception thrown when a BeanFactory is asked for a bean instance for which it cannot find a definition. This may point to a non-existing bean, a non-unique bean, or a manually registered singleton instance without an associated bean definition.

Below are some reasons BeanFactory doesn't find the bean definition.

1) Bean doesn't exist or it was not registered


         In the below example, the Student class is not annotated with @Bean or @Component, so it can not find the bean of Student.

@Configuration
public class Example {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(App.class);
        ctx.getBean(Student.class);
    }
}

class Student {
  //
}

The Student bean is not registered with annotation or XML configuration, so can not find the Student bean, it will through the error,

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException:
    No qualifying bean of type [com.adnblog.Student] is defined

There are so many ways to register the bean definitions,

1)  @Bean method in a @Configuration class or <bean> in XML configuration
2)  @Component and its meta-annotations through @ComponentScan or <context:component-scan> tag in  XML file.
and so on.


2) Multiple matching beans


     In some cases we need multiple beans of same type. In XML configuration we are defining two beans of same type e.g Student in the below configuration.

<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.0.xsd">

<bean
class ="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
        
  <bean id="school" class="com.test.School" >

  <bean id="student1" class="com.test.Student" >
       <property name="name" value="Mahesh" />
  </bean>

  <bean id="student2" class="com.test.Student" >
       <property name="name" value="Rajesh" />
  </bean>

</beans>

The below code to call the Student bean in the School class as follow,

package com.test;

import org.springframework.beans.factory.annotation.Autowired;

public class School{

     @Autowired
     private Student student;
 
     // other property and setter and getters
}

If you run the above code, will get the exception as,

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:
 No unique bean of type [com.test.Student] is defined:
  expected single matching bean but found 2: [student1, student2]

Because Spring doesn't know which bean should autowire.

To avoid this confusion or exception, should use @Qualifier annotation.

package com.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class School{

        @Autowired
        @Qualifier("student1")
        private Student student;
 
        // other property and setter and getters
}

Reference : Spring @Qualifier Annotation with example


3) Using wrong bean name


 Just as there are multiple ways to register beans, there are also multiple ways to name them.

      The name of this bean, or if plural, aliases for this bean. If left unspecified the name of the bean is the name of the annotated method. If specified, the method name is ignored.

    <bean> has the id attribute to represent the unique identifier for a bean and name can be used to create one or more aliases illegal in an (XML) id.


Thank you for visiting blog.


Related Posts:--

No comments:

Post a comment