我有以下配置:
@Configuration
public class GameConfig {
@Bean(name = "redsox")
public Team getRedSox() {
return new Team("RedSox");
}
@Bean(name = "boston")
public Team getBoston() {
return new Team("Boston");
}
@Bean @Scope(value="prototype")
public Game getGame(@Qualifier("boston") Team t1, @Qualifier("redsox") Team t2) {
return new Game( t1, t2 );
}
@Bean
GameController gameController(Game g) {
return new GameController(g);
}
}
@RestController
@RequestMapping("game")
public class GameController {
Game game;
public GameController(Game game) {
this.game = game;
}
@RequestMapping(path = "play", method = RequestMethod.GET)
public Team play() {
return game.play();
}
@RequestMapping(path = "setHomeTeam", method = RequestMethod.POST)
public void setHomeTeam(@RequestBody Team t) {
game.setHomeTeam(t);
}
}
public class Game {
private Team homeTeam;
private Team awayTeam;
public Game (Team homeTeam, Team awayTeam){
this.homeTeam = homeTeam;
this.awayTeam = awayTeam;
}
public Team play (){
Random randomGenerator = new Random();
// Generate random integers in the range 0..1
int randomInt = randomGenerator.nextInt(2);
if (randomInt == 0 )
return this.homeTeam;
else
return this.awayTeam;
}
public void setHomeTeam (Team t){
this.homeTeam = t;
}
public void setAwayTeam (Team t){
this.awayTeam = t;
}
}
@Getter @NoArgsConstructor @AllArgsConstructor
public class Team {
private String name;
}
我希望游戏不要单挑。 但是当我拨打POST请求时http://localhost:8080/game/setHomeTeam 然后我调用GET请求http://localhost:8080/game/play它会记住setHomeTeam。
我找到的唯一解决方案是以另一种方式配置gameController:
@Bean
@Scope(value="prototype")
GameController gameController(
@Qualifier("boston") Team t1,
@Qualifier("redsox") Team t2
) {
return new GameController(new Game(t1, t2));
}
但是这会将控制器+游戏创建为非Singletone。 我想只有Game non-Singletone。 有没有更好/更有效的方法?
答案 0 :(得分:2)
@Bean
@Scope(value="request",proxyMode = ScopedProxyMode.TARGET_CLASS)
public Game getGame(@Qualifier("boston") Team t1, @Qualifier("redsox") Team t2) {
return new Game( t1, t2 );
}
如果我们有界面,我们会使用:ScopedProxyMode.INTERFACES
看看http://www.baeldung.com/spring-bean-scopes
部分" 4.1。请求范围"
注释@RequestScope
等同于
@Scope(value="request",proxyMode = ScopedProxyMode.TARGET_CLASS)
或简称@RequestScope
。
如果类(游戏)是最终的,则此解决方案不可用,因为创建了代理calss。
答案 1 :(得分:2)
实现限定符的更好方法是使用注释 定义2个注释:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Redsox {
}
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Boston {
}
在配置文件中,更改以下bean:
@Bean @Redsox
public Team getRedSox() {
return new Team("RedSox");
}
@Bean @Boston
public Team getBoston() {
return new Team("Boston");
}
@Bean @Scope(value="prototype",proxyMode = ScopedProxyMode.TARGET_CLASS)
public Game getGame(@Boston Team t1, @Redsox Team t2) {
return new Game( t1, t2 );
}
答案 2 :(得分:0)
另一个选择是在 gameController 中定义:
@Lookup
public Game getGameBean(){
return null;
}
以上等效于 context.getBean(Game.class),因为您没有应用程序Spring上下文。 而且您不需要在bean定义中定义 proxyMode