I have the following configuration :
@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;
}
I would like the Game not to be singletone. but when I call POST request http://localhost:8080/game/setHomeTeam and then I call GET request http://localhost:8080/game/play it remembers the setHomeTeam.
The only solution I have found was configure gameController in another way:
@Bean
@Scope(value="prototype")
GameController gameController(
@Qualifier("boston") Team t1,
@Qualifier("redsox") Team t2
) {
return new GameController(new Game(t1, t2));
}
but this creates the controller + Game as non Singletone. I would like to have only the Game non-Singletone. Is there any better/ efficient way ?
@Bean
@Scope(value="request",proxyMode = ScopedProxyMode.TARGET_CLASS)
public Game getGame(@Qualifier("boston") Team t1, @Qualifier("redsox") Team t2) {
return new Game( t1, t2 );
}
If we had interface we would use : ScopedProxyMode.INTERFACES
Look at http://www.baeldung.com/spring-bean-scopes
section "4.1. Request Scope"
Annotation @RequestScope
is equivalent to
@Scope(value="request",proxyMode = ScopedProxyMode.TARGET_CLASS)
Or in short @RequestScope
.
If the class (Game) is final this solution is not available, since a proxy calss is created.