Java 带有Spring注释的Bean的多个配置

Java 带有Spring注释的Bean的多个配置,java,spring,annotations,Java,Spring,Annotations,在我这里的例子中,我有一个“英雄”bean,它可以被注入一个“武器”bean。英雄和武器都是原型范围(我们可以有多个英雄,他们不会共享武器) 我想要的是一个名为“战士”的英雄配置,注入“剑”武器,以及一个名为“弓箭手”的英雄配置,注入“弓”武器。然后在我的申请中我会打电话给 context.getBean("Warrior"); 每次我都想换一个新战士 我知道如何使用XML实现这一点,但我想知道是否可以使用注释实现这一点?如果是,我该怎么做?我使用的是Spring 4。LuiggiMendoz

在我这里的例子中,我有一个“英雄”bean,它可以被注入一个“武器”bean。英雄和武器都是原型范围(我们可以有多个英雄,他们不会共享武器)

我想要的是一个名为“战士”的英雄配置,注入“剑”武器,以及一个名为“弓箭手”的英雄配置,注入“弓”武器。然后在我的申请中我会打电话给

context.getBean("Warrior");
每次我都想换一个新战士


我知道如何使用XML实现这一点,但我想知道是否可以使用注释实现这一点?如果是,我该怎么做?我使用的是Spring 4。

LuiggiMendoza评论的示例(自动连接和限定setter)

按照编程到接口的脚本,我们有
Hero
接口

public interface Hero {
    void killOrBeKilled();
}
我们还将有一个
AbstractHero
抽象类来组合一些常见的功能。请注意,我们没有实现
setwearm
方法。我们将把它留给具体的课堂

public abstract class AbstractHero implements Hero {
    protected Weapon weapon;

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

    protected abstract void setWeapon(Weapon weapon);
}
这是我们将使用的方法。注意,您不必创建自己的限定符。您可以简单地使用
@qualifier(“qualifierName”)
进行匹配。我这么做只是因为我可以:P

对于
Warrior
我们将使用
@SwordType
限定符

@Component  
public class Warrior extends AbstractHero {
    @SwordType
    @Autowired
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
}
@Component
public class Archer extends AbstractHero {
    @BowType
    @Autowired
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;   
    }
}
对于
Archer
我们将使用
@BowType
限定符

@Component  
public class Warrior extends AbstractHero {
    @SwordType
    @Autowired
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
}
@Component
public class Archer extends AbstractHero {
    @BowType
    @Autowired
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;   
    }
}
在我们的
武器
具体类中,我们还需要使用适当的限定符对类进行注释

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!");   
    }
}
@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();
    }
}
当我们运行应用程序时,将根据我们的限定符正确注入武器类型

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!");   
    }
}
@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();
    }
}
结果

剑劈了
鞠躬开始滑行

另外,我忘记了
@Scope(“prototype”)
注释

  • 有关使用限定符的更多信息,请参阅

是的。这是可能的。我还没有测试过它,但您似乎可以在子类中自动连接setter,以指定您的
英雄将使用的
武器的具体类型。@LuiggiMendoza如果我只有一种类型的英雄,这将起作用,但是你如何将武器类型与英雄类型联系起来呢?你可以用我的评论在子类的setter中定义
@Autowired
@Qualifier
,在你的例子中,在
战士
弓箭手
类中,而在
英雄
类中,你只定义
武器
。非常好的例子。我试图避免的是创建Warrior和Archer子类,但我认为这已经足够接近了。