@Scope("prototype")表示 bean 的作用域不会创建新的 bean。

9 浏览
0 Comments

@Scope("prototype")表示 bean 的作用域不会创建新的 bean。

我想在我的控制器中使用一个带注解的原型Bean。但是Spring仅仅创建了一个单例Bean。以下是代码:

@Component
@Scope("prototype")
public class LoginAction {
  private int counter;
  public LoginAction(){
    System.out.println(" counter is:" + counter);
  }
  public String getStr() {
    return " counter is:"+(++counter);
  }
}

控制器代码:

@Controller
public class HomeController {
    @Autowired
    private LoginAction loginAction;
    @RequestMapping(value="/view", method=RequestMethod.GET)
    public ModelAndView display(HttpServletRequest req){
        ModelAndView mav = new ModelAndView("home");
        mav.addObject("loginAction", loginAction);
        return mav;
    }
    public void setLoginAction(LoginAction loginAction) {
        this.loginAction = loginAction;
    }
    public LoginAction getLoginAction() {
        return loginAction;
    }
    }

Velocity模板:

 LoginAction counter: ${loginAction.str}

Spring的config.xml启用了组件扫描:

    
    
    

我每次都会获得一个增加的计数值。无法找出我错在哪里了!

更新

如@gkamal所建议的那样,我使HomeController成为webApplicationContext。这解决了问题。

更新后的代码:

@Controller
public class HomeController {
    @Autowired
    private WebApplicationContext context;
    @RequestMapping(value="/view", method=RequestMethod.GET)
    public ModelAndView display(HttpServletRequest req){
        ModelAndView mav = new ModelAndView("home");
        mav.addObject("loginAction", getLoginAction());
        return mav;
    }
    public LoginAction getLoginAction() {
        return (LoginAction) context.getBean("loginAction");
    }
}

admin 更改状态以发布 2023年5月21日
0
0 Comments

从Spring 2.5开始,实现这一点非常简单(也很优雅)。

你可以简单地改变@Scope注解的参数proxyModevalue

通过这个技巧,你可以避免编写额外的代码或每次需要在单例bean内部注入ApplicationContext时进行注入。

例如:

@Service 
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)  
public class LoginAction {}

使用上面的配置,即使控制器是单例,HomeController内的LoginAction始终是原型。

0
0 Comments

“scope prototype”意味着每次你向spring(使用getBean或依赖注入)请求一个实例时,它都会创建一个新实例并提供对该实例的引用。

在你的示例中,会创建一个新的LoginAction实例并将其注入到你的HomeController中。如果你有另一个控制器,其中注入了LoginAction,则会获得不同的实例。

如果你想每次调用时都获得不同的实例-那么你需要每次调用getBean-将其注入到单例bean中将无法实现该目的。

0