Multiple Bean Configurations with Spring Annotations

In my example here, I have a "Hero" bean that can be injected with the "Weapon" bean. Both Hero and Weapons are prototypes (we can have multiple heroes and they won't share weapons).

What I want to have is a hero configuration called "Warrior" which introduces the "Sword" weapon and a hero configuration called "Archer" which introduces the weapon "Bow". Then in my application I would call

context.getBean("Warrior");

      

every time i want to get a new warrior.

I know how to do this with XML, but I was wondering if it could be done with annotations? If so, how do I do it? I am using Spring 4.

+3


source to share


1 answer


Example of LuiggiMendoza comment (auto-install and setter detection)

Sticking with script programming to interfaces, we have an interface Hero

public interface Hero {
    void killOrBeKilled();
}

      

We will also have an abstract class AbstractHero

to collect some common functionality. Please note that we are not implementing the method setWeapon

. We'll leave this in a specific class.

public abstract class AbstractHero implements Hero {
    protected Weapon weapon;

    public void killOrBeKilled() {
        weapon.secretWeaponManeuver();
    }

    protected abstract void setWeapon(Weapon weapon);
}

      

And here are the Qualifiers we'll be using. Please note, you don't need to create your own qualifiers. You can just use @Qualifer("qualifierName")

for your mappings. I only did it because I could: P

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
public @interface BowType { }

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
public @interface SwordType { }

      

For Warrior

we will use the qualifier@SwordType

@Component  
public class Warrior extends AbstractHero {
    @SwordType
    @Autowired
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
}

      

And for Archer

we will use the qualifier@BowType



@Component
public class Archer extends AbstractHero {
    @BowType
    @Autowired
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;   
    }
}

      

In our Weapons

concrete classes, we will also need to annotate the classes with the appropriate qualifiers

public interface Weapon {
    void secretWeaponManeuver();
}

@BowType    
@Component
public class Bow implements Weapon {
    public void secretWeaponManeuver() {
        System.out.println("Bow goes Slinnnggggg!");    
    }
}

@SwordType
@Component
public class Sword implements Weapon {
    public void secretWeaponManeuver() {
        System.out.println("Sword goes Slassshhhh!");   
    }
}

      

When we launch the application, the weapon types will be entered correctly based on our qualifiers

@Configuration  
@ComponentScan(basePackages = {"com.stackoverflow.spring.hero"})
public class Config { }

public class Application {
    public static void main(String[] args) {
        AbstractApplicationContext context = 
                new AnnotationConfigApplicationContext(Config.class);

        Hero warrior = context.getBean(Warrior.class);
        warrior.killOrBeKilled();

        Hero archer = context.getBean(Archer.class);
        archer.killOrBeKilled();

        context.close();
    }
}

      

Result

The sword goes Slassshhh!
The bow goes Slinnnggggg!

PS I forgot the annotation @Scope("prototype")

.

+2


source







All Articles