{"id":12792,"date":"2015-12-08T22:03:00","date_gmt":"2015-12-08T21:03:00","guid":{"rendered":"https:\/\/touk.pl\/blog\/?guid=8c98115a8907eacd17a0f30552f44a63"},"modified":"2023-04-27T11:32:03","modified_gmt":"2023-04-27T09:32:03","slug":"spring-autowire-with-qualifiers","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2015\/12\/08\/spring-autowire-with-qualifiers\/","title":{"rendered":"Spring autowire with qualifiers"},"content":{"rendered":"<h2 id=\"introduction\">Introduction<\/h2>\n<p><code>Autowired<\/code> is great annotation, which by default inject beans by type to annotated element (constructor, setter or field). But how to use it, when there is more than one bean of requested type.<\/p>\n<h2 id=\"autowired-with-one-bean\"><code>Autowired<\/code> with one bean<\/h2>\n<p>Suppose we will work with small interface:<\/p>\n<pre class=\"brush: java\">interface IHeaderPrinter {<br \/>    String printHeader(String header)<br \/>}<\/pre>\n<p>When we have only one bean implementing <code>IHeaderPrinter<\/code>:<\/p>\n<pre class=\"brush: java\">@Component<br \/>class HtmlHeaderPrinter implements IHeaderPrinter{<br \/>    @Override<br \/>    String printHeader(String header) {<br \/>        return \"&lt;h1&gt;$header&lt;\/h1&gt;\"<br \/>    }<br \/>}<\/pre>\n<p>then everything works great and test passes.<\/p>\n<pre class=\"brush: java\">@Autowired<br \/>IHeaderPrinter headerPrinter<br \/><br \/>@Test<br \/>void shouldPrintHtmlHeader() {<br \/>    assert headerPrinter.printHeader(&#039;myTitle&#039;) == &#039;&lt;h1&gt;myTitle&lt;\/h1&gt;&#039;<br \/>}<\/pre>\n<h2 id=\"two-implementations\">Two implementations<\/h2>\n<p>But what will happen, if we add another implementation of <code>IHeaderPrinter<\/code>, e. g. <code>MarkdownHeaderPrinter<\/code>?<\/p>\n<pre class=\"brush: java\">@Component<br \/>class MarkdownHeaderPrinter implements IHeaderPrinter {<br \/>    @Override<br \/>    String printHeader(String header) {<br \/>        return \"# $header\"<br \/>    }<br \/>}<\/pre>\n<p>Now out test with fail with exception:<\/p>\n<pre class=\"brush: java\">Error creating bean with name &#039;com.blogspot.przybyszd.spring.autowire.SpringAutowireWithQualifiersApplicationTests&#039;: Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.blogspot.przybyszd.spring.autowire.IHeaderPrinter com.blogspot.przybyszd.spring.autowire.SpringAutowireWithQualifiersApplicationTests.headerPrinter; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.blogspot.przybyszd.spring.autowire.IHeaderPrinter] is defined: expected single matching bean but found 2: markdownHeaderPrinter,htmlHeaderPrinter<\/pre>\n<p>We have to decide which implementation we want to use in our test, so &#8230;<\/p>\n<h2 id=\"two-implementations-with-qualifier\">Two implementations with <code>Qualifier<\/code><\/h2>\n<p>Each bean is registered with name equal its class. For example <code>HtmlHeaderPrinter<\/code> is named <code>htmlHeaderPrinter<\/code>. The name is also its qualifier. We have to tell <code>Autowired<\/code>, that it should inject <code>htmlHeaderPrinter<\/code>:<\/p>\n<pre class=\"brush: java; highlight: 2\">@Autowired<br \/>@Qualifier(&#039;htmlHeaderPrinter&#039;)<br \/>IHeaderPrinter headerPrinter<\/pre>\n<p>Now our test passes again.<\/p>\n<h2 id=\"two-implementations-qualified-by-field-name\">Two implementations qualified by field name<\/h2>\n<p>If field is names like implementing class (for example <code>htmlHeaderPrinter<\/code>), then this class implementation will be injected:<\/p>\n<pre class=\"brush: java\">@Autowired<br \/>IHeaderPrinter htmlHeaderPrinter<\/pre>\n<p>And test passes:<\/p>\n<pre class=\"brush: java\">@Test<br \/>void shouldPrintHtmlHeader() {<br \/>    assert htmlHeaderPrinter.printHeader(&#039;myTitle&#039;) == &#039;&lt;h1&gt;myTitle&lt;\/h1&gt;&#039;<br \/>}<\/pre>\n<p>Thanks to <code>@marcinjasion<\/code>.<\/p>\n<h2 id=\"two-implementation-with-primary\">Two implementation with <code>Primary<\/code><\/h2>\n<p>We often have one implementation which we almost always want to inject, so do we still have to put <code>Qualifier<\/code> with its name wherever we want to use it? No.<\/p>\n<p>We could mark one implementation as <code>Primary<\/code> and this bean will be wired by default (unless we explicit give another <code>Qualifier<\/code> to use injection point):<\/p>\n<pre class=\"brush: java; highlight: 2\">@Component<br \/>@Primary<br \/>class HtmlHeaderPrinter implements IHeaderPrinter{<br \/>    \/\/ ...<br \/>}<\/pre>\n<pre class=\"brush: java\">@Autowired<br \/>IHeaderPrinter headerPrinter<\/pre>\n<h2 id=\"summary\">Summary<\/h2>\n<p><code>Autowired<\/code> annotation allows us to inject dependencies to beans. It works great without additional configuration, when each bean could be uniquely find by type. When we have more than one bean, that could be injected, we have to use <code>Qualifier<\/code> or <code>Primary<\/code> annotation to help it find desired implementation.<\/p>\n<p>Source code is available <a href=\"https:\/\/github.com\/alien11689\/spring-autowire-with-qualifiers\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"Introduction Autowired is great annotation, which by default inject beans by type to annotated element (constructor, setter or&hellip;\n","protected":false},"author":54,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[540,585,586,42],"class_list":{"0":"post-12792","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-dependency-injection","8":"tag-primary","9":"tag-qualifier","10":"tag-spring-framework"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12792","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/54"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=12792"}],"version-history":[{"count":11,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12792\/revisions"}],"predecessor-version":[{"id":15671,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/12792\/revisions\/15671"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=12792"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=12792"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=12792"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}