@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 { ..... ..... ..... }
- 使用固定值在JPA映射枚举?
- servlet和web服务的区别
- hibernate与MongoDB
- servlet中的<mvc:annotation-driven />和<context:annotation-config />有什么区别?
- 无法findXML模式命名空间的Spring NamespaceHandler
- 获得exception:没有定义名为“springSecurityFilterChain”的bean
- Spring Data JPA通过embedded对象属性来查找
- 如何使用Spring Security在Java代码中检查“hasRole”?
- dependency injection容器有什么好处?