To bootstrap a plain Spring app (no Boot), create a main package with a Main/App class —
that’s where the application context gets created, from an AnnotationConfigApplicationContext
pointed at a @Configuration class.
package dev.thesarfo;
import dev.thesarfo.beans.Owner;import dev.thesarfo.config.ProjectConfig;import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App { public static void main(String[] args) { try (AnnotationConfigApplicationContext c = new AnnotationConfigApplicationContext(ProjectConfig.class)) { Owner o = c.getBean(Owner.class); System.out.println(o); } }}Disambiguating multiple beans of the same type
Say we have a Cat bean and an Owner that depends on one:
package dev.thesarfo.beans;
public class Cat {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
@Override public String toString() { return "Cat{name='" + name + "'}"; }}If the config defines two Cat beans, Spring has no way to know which one to inject — you need
@Qualifier on both the bean definitions and the injection point, naming which one you want:
package dev.thesarfo.config;
import dev.thesarfo.beans.Cat;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;
@Configuration@ComponentScan(basePackages = "dev.thesarfo.beans")public class ProjectConfig {
@Bean @Qualifier("cat1") // the name this bean will be stored under in the context public Cat cat1() { Cat c = new Cat(); c.setName("Tom"); return c; }
@Bean @Qualifier("cat2") // @Primary // alternative: mark one bean as the default used when no qualifier is given public Cat cat2() { Cat c = new Cat(); c.setName("Leo"); return c; }}package dev.thesarfo.beans;
import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Component;
@Componentpublic class Owner {
@Qualifier("cat2") // tell the context which Cat bean to use private Cat cat;
public Cat getCat() { return cat; }
public void setCat(Cat cat) { this.cat = cat; }
@Override public String toString() { return "Owner{cat=" + cat + "}"; }}Owner resolves to the cat2 bean (“Leo”) specifically. The alternative to @Qualifier at every
injection point is @Primary on one of the candidate bean definitions, marking it as the default
whenever no explicit qualifier is given.