@Scope(“prototype”)bean作用域不会创build新的bean

我想在我的控制器中使用注释的原型bean。 但是Spring正在创build一个singleton 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; } } 

速度模板:

  LoginAction counter: ${loginAction.str} 

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

  <context:annotation-config /> <context:component-scan base-package="com.springheat" /> <mvc:annotation-driven /> 

我每次都得到递增的计数。 不知道我哪里错了!

更新

正如@gkamal所build议的 ,我做了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", loginAction); return mav; } public LoginAction getLoginAction() { return (LoginAction) context.getBean("loginAction"); } } 

范围原型意味着每当你为一个实例询问spring(getBean或dependency injection)时,它将创build一个新的实例并给出一个引用。

在你的例子中,一个新的LoginAction实例被创build并注入到你的HomeController中。 如果你有另外一个你注入LoginAction的控制器,你会得到一个不同的实例。

如果你想要每个调用都有一个不同的实例 – 那么你需要每次调用getBean – 注入一个单例bean不会达到这个目的。

仅仅因为注入控制器的bean是原型范围的,并不意味着控制器是!

@controller是一个单例对象,如果将一个prototype bean注入到一个singleton类中,原型bean也将作为singleton,除非你使用lookup-method属性来为每个调用创build一个新的prototype bean实例。

使用请求范围@Scope("request")为每个请求获取bean,或者@Scope("session")为每个会话'user'

使用ApplicationContextAware将您绑定到Spring(这可能会也可能不是问题)。 我build议传入一个LoginActionFactory ,你可以在每次需要的时候请求一个LoginAction的新实例。

正如nicholas.hauschild所提到的,注入Spring的上下文不是一个好主意。 在你的情况下,@Scope(“请求”)就足以解决它。 但是假设你需要在控制器方法中使用几个LoginAction实例。 在这种情况下,我build议创build供应商的bean( Spring 4解决scheme):

  @Bean public Supplier<LoginAction> loginActionSupplier(LoginAction loginAction){ return () -> loginAction; } 

然后注入控制器:

 @Controller public class HomeController { @Autowired private Supplier<LoginAction> loginActionSupplier; 

你的控制器也需要@Scope(“prototype”)定义

喜欢这个:

 @Controller @Scope("prototype") public class HomeController { ..... ..... ..... }