N. Sakhnov
N. Sakhnov

Reputation: 3

How use annotation-based config in place of XML-based config

I apply the Spring framework for dependency injection by XML-based configuration.

For example, I have 3 classes:

  1. public class Robot implements IRobot{

       IHand hand;

       -//-

     }

  2. public class SonyHand implements IHand{ -//- }

  3. public class ToshibaHand implements IHand{ -//- }

Further I have the XML file:

<beans ...>

  <bean id="robot1" class="somepackage.Robot.class">
    <property name="hand" ref="sonyHand">
  </bean>

  <bean id="robot2" class="somepackage.Robot.class">
    <property name="hand" ref="toshibaHand">
  </bean>

  <bean id="sonyHand" class="somepackage.SonyHand.class"/>


  <bean id="toshibaHand" class="somepackage.ToshibaHand.class"/>       

</beans>

As a consequence, Spring IoC(container) will create four beans(objects) in all.

Bean robot1(a sonyHand bean will be introduced into it).

Bean robot2(a toshibaHand bean will be introduced into it).

Bean sonyHand.

Bean toshibaHand.

Question is that, can I do exactly the same thing by pure annotation-based configuration? If I do, then how? I've tried this:

@Configuration
public class AppConfig{

  @Bean
  public Robot robot1(){
    return new Robot();
  }

  @Bean
  public Robot robot2(){
    return new Robot();
  }

  @Bean
  @Qualifier("sonyH")
  public SonyHand sonyHand(){
    return new SonyHand();
  }

  @Bean
  @Qualifier("toshibaH")
  public ToshibaHand toshibaHand(){
    return new ToshibaHand();
  }
}

Slightly changed the classes:

  1. public class Robot implements IRobot{

       @Autowired("sonyH")
       IHand hand;

       -//-

     }

  2. public class SonyHand implements IHand{ -//- }

  3. public class ToshibaHand implements IHand{ -//- }

There is almost nothing left in the XML file:

<beans ...>

  <context:component-scan base-package="somepackage"/>    

</beans>

This all works, but this is not what I need because the beans that will be created by the container will be slightly different from the previous example:

Bean robot1(a sonyHand bean will be introduced into it).

Bean robot2(and again a sonyHand bean will be introduced into it).

Bean sonyHand.

Bean toshibaHand.

And I know why this happens(because of @Autowired("sonyH")), but I do not know how to fix it in such a way that it works like in the case with XML-based configuration.

Upvotes: 0

Views: 83

Answers (1)

pvpkiran
pvpkiran

Reputation: 27018

Slightly refactor your class

@Configuration
public class AppConfig{

  @Bean
  public Robot robot1(IHand sonyH){
    return new Robot(sonyH);
  }

  @Bean
  public Robot robot2(IHand toshibaH){
    return new Robot(toshibaH);
  }

  @Bean(name = "sonyH")
  public SonyHand sonyHand(){
    return new SonyHand();
  }

  @Bean(name = "toshibaH")
  public ToshibaHand toshibaHand(){
    return new ToshibaHand();
  }
}

Now if you try to Autowire like this

@Autowired
Robot robot1 // this will have sonyH instance

@Autowired
Robot robot2 // this will have toshibaH instance

Upvotes: 1

Related Questions