Tags

, ,

Many years ago when I was learning Spring, I was told I need to declare all the beans or components in a XML bean configuration file, so that Spring container can detect and register my beans or components.

Now things have changed, Spring is able to auto scan, detect and instantiate your beans from pre-defined project package, no more tedious beans declaration in the XML file.

In XML mode we can define a bean through the following way

<beans>
<bean id=”myService” name=”myService” class=”com.foo.MyServiceImpl”/>
</beans>

Now through annotation you can do it as :

@Configuration
public class AppConfig {

@Bean
public MyService myService() {
return new MyServiceImpl();
}

}

Both will result in a bean named myService being available in the ApplicationContext, bound to an object instance of type MyServiceImpl.

When @Beans have dependencies on one another, expressing that dependency is as simple as having one bean method call another:

@Configuration
public class AppConfig {

@Bean
public Foo foo() {
return new Foo(bar());
}

@Bean
public Bar bar() {
return new Bar();
}

}

In the example above, the foo bean receives a reference to bar via constructor injection.

Spring beans are identified byType(by default). In XML based configuration you can define a unique id for each bean. In annotation mode,we use @Autowired instead.The autowiring by type may lead to multiple candidates. How to resolve that? One way to accomplish this is with Spring’s @Qualifier annotation. The second way is to use @Resource ( According to http://bit.ly/186AFZe In contrast to @Autowired which is applicable to fields, constructors and multi-argument methods (allowing for narrowing through qualifier annotations at the parameter level), @Resource is only supported for fields and bean property setter methods with a single argument. Thus, stick with qualifiers if your injection target is a constructor or a multi-argument method.).

What we are interested in here is the @Qualifier annotation. It  is much more flexible since it can also be used with constructors and multiple parameter methods.

If there isn’t a match and @Autowired is marked as required, then a BeanCreationException will be thrown. When @Qualifier is used on constructors or methods with multiple parameters, any parameters without the annotation will still be autowired by type.

Let us consider the following sample

@Component
public class SomeClass {
@Autowired(required=true)
public SomeClass(OtherClass bean1, OtherClass bean2) {

}
}

And an application context with :

bean1″ class=”OtherClass” />
bean2″ class=”OtherClass” />

How to do it in annotation?

@Component
public class SomeClass {
@Autowired(required=true)
public SomeClass(@Qualifier(“bean1”) OtherClass bean1, @Qualifier(“bean2”) OtherClass bean2) {

}
}

Please be noted in the above sample, the constructor parameters are the same type.

=====================

Summary in this post we have compared two ways of defining beans in Spring. At the same time we have paid more attention to the @Qualifier annotation in conjunction with the @Autowired annotation.

Advertisements