tin*_*tin 120 spring spring-mvc
我想在我的控制器中使用带注释的原型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);
}
}
Run Code Online (Sandbox Code Playgroud)
控制器代码:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
速度模板:
LoginAction counter: ${loginAction.str}
Run Code Online (Sandbox Code Playgroud)
Spring config.xml启用了组件扫描:
<context:annotation-config />
<context:component-scan base-package="com.springheat" />
<mvc:annotation-driven />
Run Code Online (Sandbox Code Playgroud)
我每次都得到一个递增的计数.无法弄清楚我哪里出错了!
更新
正如@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");
}
}
Run Code Online (Sandbox Code Playgroud)
gka*_*mal 141
范围原型意味着每次向实例请求spring(getBean或依赖注入)时,它都会创建一个新实例并提供对它的引用.
在您的示例中,将创建一个新的LoginAction实例并将其注入HomeController.如果你有另一个控制器注入LoginAction,你将得到一个不同的实例.
如果你想为每个调用一个不同的实例 - 那么你每次都需要调用getBean - 注入单例bean将无法实现.
db8*_*b80 18
从Spring 2.5开始,就有了一种非常简单(优雅)的方法来实现这一目标.
你可以只改变PARAMS proxyMode和value中的@Scope注释.
使用此技巧,您可以避免每次在单例bean中需要原型时编写额外的代码或注入ApplicationContext.
例:
@Service
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class LoginAction {}
Run Code Online (Sandbox Code Playgroud)
使用上面的配置LoginAction(内部HomeController)始终是原型,即使控制器是单例.
小智 9
@controller是一个单例对象,如果将一个原型bean注入一个单独的类,它将使原型bean也成为单例,除非你指定使用lookup-method属性,它实际上为你做的每个调用创建一个新的prototype bean实例.
正如nicholas.hauschild所提到的,注入 Spring 上下文不是一个好主意。在您的情况下,@Scope("request") 足以修复它。但是假设您需要几个LoginActionin 控制器方法的实例。在这种情况下,我建议创建供应商的 bean ( Spring 4解决方案):
@Bean
public Supplier<LoginAction> loginActionSupplier(LoginAction loginAction){
return () -> loginAction;
}
Run Code Online (Sandbox Code Playgroud)
然后将其注入控制器:
@Controller
public class HomeController {
@Autowired
private Supplier<LoginAction> loginActionSupplier;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
198615 次 |
| 最近记录: |