范围原型不工作
scope prototype not working
我有以下配置:
@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));
}
但这会将控制器 + 游戏创建为非单音。
我只想拥有非单音游戏。
有没有更好/有效的方法?
@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
.
如果 class(游戏)是最终的,则此解决方案不可用,因为已创建代理调用。
实现限定符的更好方法是使用注释
定义 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 );
}
另一种选择是在 gameController 中定义:
@Lookup
public Game getGameBean(){
return null;
}
以上等同于 context.getBean(Game.class) 因为您没有应用程序 spring 上下文。
而且你不需要在bean定义
中定义proxyMode
我有以下配置:
@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));
}
但这会将控制器 + 游戏创建为非单音。 我只想拥有非单音游戏。 有没有更好/有效的方法?
@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
.
如果 class(游戏)是最终的,则此解决方案不可用,因为已创建代理调用。
实现限定符的更好方法是使用注释 定义 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 );
}
另一种选择是在 gameController 中定义:
@Lookup
public Game getGameBean(){
return null;
}
以上等同于 context.getBean(Game.class) 因为您没有应用程序 spring 上下文。 而且你不需要在bean定义
中定义proxyMode