Thursday, 11 May 2017

Spring: Points to consider while autowiring

When you apply @Autowired annotation on any property, mehtod (or) constructor, the autowiring fails whenever zero candidate beans are available; the default behavior is to treat annotated methods, constructors, and fields as indicating required dependencies.

Example
public class Book {

 @Autowired
 private Author author;

}

I Autowired author bean, if I don’t define the bean of type Author, in my configuraiton file, Spring throws UnsatisfiedDependencyException.

Find the complete working example below.


Author.java
package com.sample.pojo;

public class Author {
 private String firstName;
 private String lastName;
 private String dateOfBirth;
 private String country;

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getDateOfBirth() {
  return dateOfBirth;
 }

 public void setDateOfBirth(String dateOfBirth) {
  this.dateOfBirth = dateOfBirth;
 }

 public String getCountry() {
  return country;
 }

 public void setCountry(String country) {
  this.country = country;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Author [firstName=").append(firstName).append(", lastName=").append(lastName)
    .append(", dateOfBirth=").append(dateOfBirth).append(", country=").append(country).append("]");
  return builder.toString();
 }

}

Book.java
package com.sample.pojo;

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

public class Book {
 private String title;
 private int noOfPages;
 private float price;

 @Autowired
 private Author author;

 public Book() {

 }

 public void setTitle(String title) {
  this.title = title;
 }

 public void setNoOfPages(int noOfPages) {
  this.noOfPages = noOfPages;
 }

 public void setPrice(float price) {
  this.price = price;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Book [title=").append(title).append(", noOfPages=").append(noOfPages).append(", price=")
    .append(price).append(", author=").append(author).append("]");
  return builder.toString();
 }

}

myConfiguration.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

 <context:annotation-config />

 <bean id="book1" class="com.sample.pojo.Book">
  <property name="title" value="Vedanta An Art of Dying" />
  <property name="noOfPages" value="164" />
  <property name="price" value="90" />
 </bean>


</beans>

HelloWorld.java
package com.sample.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.sample.pojo.Book;

public class HelloWorld {
 public static void main(String args[]) {
  ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "myConfiguration.xml" });

  Book book = context.getBean("book1", Book.class);

  System.out.println(book);

  ((ClassPathXmlApplicationContext) context).close();
 }
}

Try to run ‘HelloWorld.java’ application, you will end up in following error.
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'book1': Unsatisfied dependency expressed through field 'author'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.sample.pojo.Author]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569)
 at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1219)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
 at com.sample.test.HelloWorld.main(HelloWorld.java:10)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.sample.pojo.Author]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1463)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1094)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1056)
 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566)
 ... 15 more

How to resolve above problem?
There are two ways.
a.   Define a bean of type Author in myConfiguration.xml file
b.   Update the Autowired annotation like ‘@Autowired(required=false)’.

Update Book class like below and re run ‘HelloWorld.java’ application.


Book.java
package com.sample.pojo;

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

public class Book {
 private String title;
 private int noOfPages;
 private float price;

 @Autowired(required = false)
 private Author author;

 public Book() {

 }

 public void setTitle(String title) {
  this.title = title;
 }

 public void setNoOfPages(int noOfPages) {
  this.noOfPages = noOfPages;
 }

 public void setPrice(float price) {
  this.price = price;
 }

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("Book [title=").append(title).append(", noOfPages=").append(noOfPages).append(", price=")
    .append(price).append(", author=").append(author).append("]");
  return builder.toString();
 }

}


Previous                                                 Next                                                 Home

No comments:

Post a Comment