Monday, 26 February 2018

7.0 Dependency injection with Annotations and Autowiring

Spring Auto Wiring - For Dependency injection spring  can use auto wiring. Spring will look for a class that matches the property , match can be class or interface. After finding the match spring will automatically inject it and it is known as spring auto wiring.


Example of Constructor Injection using Annotations

-----------------------------------------------------------------------------------------
BaseBallCoach.java
-----------------------------------------------------------------------------------------
package com.demo.spring;

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

@Component
public class BaseBallCoach implements Coach {

@Autowired
public BaseBallCoach(FortuneService thefortuneservce){
fortuneservce=thefortuneservce;
}


@Override
public String getDailyWorkout() {
return "practice 30 mins daily";
}


@Override
public String getFortuneService() {
// TODO Auto-generated method stub
return fortuneservce.getFortuneService();
}


}


-----------------------------------------------------------------------------------------
applicationContext.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">

 <!-- initializing component scanning -->
 <context:component-scan base-package="com.demo.spring"></context:component-scan>

</beans>



-----------------------------------------------------------------------------------------
MyApp.java
-----------------------------------------------------------------------------------------
package com.demo.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyApp {

public static void main(String[] args) {
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Coach obj=context.getBean(Coach.class);
System.out.println(obj.getDailyWorkout());
System.out.println(obj.getFortuneService());
context.close();
}

}


-----------------------------------------------------------------------------------------
FortuneService.java
-----------------------------------------------------------------------------------------
package com.demo.spring;

public interface FortuneService {
public String getFortuneService();
}




Example of Setter Injection using Annotations
-----------------------------------------------------------------------------------------
BaseBallCoach.java
-----------------------------------------------------------------------------------------
package com.demo.spring;

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

@Component
public class BaseBallCoach implements Coach {


public BaseBallCoach(){
System.out.println("BaseBallCoach : inside no-arg constructor");
}

@Autowired
public void setFortuneservce(FortuneService fortuneservce) {
System.out.println("BaseBallCoach : inside fortuneservice setter");
this.fortuneservce = fortuneservce;
}

@Override
public String getDailyWorkout() {
return "practice 30 mins daily";
}



@Override
public String getFortuneService() {
return fortuneservce.getFortuneService();
}

}


Example of Any Method Injection using Annotations
-----------------------------------------------------------------------------------------
BaseBallCoach.java
-----------------------------------------------------------------------------------------
package com.demo.spring;

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

@Component
public class BaseBallCoach implements Coach {
private FortuneService fortuneservce;

public BaseBallCoach(){
System.out.println("BaseBallCoach : inside no-arg constructor");
}

@Autowired
public void doRandomStuff(FortuneService fortuneservce) {
System.out.println("BaseBallCoach : inside doRandomStuff method");
this.fortuneservce = fortuneservce;
}

@Override
public String getDailyWorkout() {
return "practice 30 mins daily";
}


@Override
public String getFortuneService() {
return fortuneservce.getFortuneService();
}

}



Example of Field Injection using Annotations
-----------------------------------------------------------------------------------------
BaseBallCoach.java
-----------------------------------------------------------------------------------------
package com.demo.spring;

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

@Component
public class BaseBallCoach implements Coach {
@Autowired
private FortuneService fortuneservce;

public BaseBallCoach(){
System.out.println("BaseBallCoach : inside no-arg constructor");
}

@Override
public String getDailyWorkout() {
return "practice 30 mins daily";
}


@Override
public String getFortuneService() {
// TODO Auto-generated method stub
return fortuneservce.getFortuneService();
}

}


When there is multiple dependency injection is available
-----------------------------------------------------------------------------------------
RandomFortuneService .java
-----------------------------------------------------------------------------------------
package com.demo.spring;

import org.springframework.stereotype.Component;

@Component
public class RandomFortuneService implements FortuneService {

@Override
public String getFortuneServie() {
return "Hello random service";
}

}




-----------------------------------------------------------------------------------------
ERROR
-----------------------------------------------------------------------------------------
Feb 26, 2018 3:45:16 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@41975e01: startup date [Mon Feb 26 03:45:16 IST 2018]; root of context hierarchy
Feb 26, 2018 3:45:16 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
BaseBallCoach : inside no-arg constructor
Feb 26, 2018 3:45:16 AM org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'baseBallCoach': Unsatisfied dependency expressed through field 'fortuneservce'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.demo.spring.FortuneService' available: expected single matching bean but found 2: happyFortuneService,randomFortuneService
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'baseBallCoach': Unsatisfied dependency expressed through field 'fortuneservce'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.demo.spring.FortuneService' available: expected single matching bean but found 2: happyFortuneService,randomFortuneService
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:367)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1340)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
at com.demo.spring.MyApp.main(MyApp.java:8)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.demo.spring.FortuneService' available: expected single matching bean but found 2: happyFortuneService,randomFortuneService
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:215)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1111)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1060)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:578)
... 15 more



Resolution using Qualifier Annotation
-----------------------------------------------------------------------------------------
BaseBallCoach.java
-----------------------------------------------------------------------------------------
package com.demo.spring;

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

@Component
public class BaseBallCoach implements Coach {
@Autowired
@Qualifier("happyFortuneService")
private FortuneService fortuneservce;

public BaseBallCoach(){
System.out.println("BaseBallCoach : inside no-arg constructor");
}
@Override
public String getDailyWorkout() {
return "practice 30 mins daily";
}

@Override
public String getFortuneServie() {
return fortuneservce.getFortuneService();
}

}


No comments:

Post a Comment