在单例的bean中使用session、request范围的bean有很多应用场景,比如说在电子商务系统中需要为每个会话创建一个购物车bean,如果是使用单例模式的购物车bean那么所有用户都会向同一个公务车中添加商品。
在spring初始化的时候创建单例bean时,不会向bean中注入session、request范围bean的实例而是注入他们的代理,当有会话产生时才会实例化这些bean,当调用这些bean的方法时代理会委托给回话内真实的bean。
第一种方式(推荐)
/**
* 创建一个接口并写出他的实现类,
* proxyMode设置为ScopedProxyMode.INTERFACES
*/
@Service
@Scope(value = WebApplicationContext.SCOPE_SESSION,
proxyMode = ScopedProxyMode.INTERFACES)
public class SessionService implements ISessionService{
public String get(){
return this.toString();
}
}
/**
*在单例bean中注入接口类型的bean
*/
@Autowired
ISessionService sessionService;
@RequestMapping("/t.do")
@ResponseBody
public Object t(){
return sessionService.get()+"
"+this.toString();
}
第二种方法
/**
*针对具体的类,这种情况Spring没法创建基于接口的代理了,
*所以它必须使用CGLib来生成基于类的代理。
*所以如果bean是具体的类proxyMode必须设置成ScopedProxyMode.TARGET_CLASS
*/
@Service
@Scope(value = WebApplicationContext.SCOPE_SESSION,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionService{
/**
*
* @return
*/
public String get(){
return this.toString();
}
}
/**
*在单例模式中直接注入就行
*/
@Autowired
SessionService sessionService;
@RequestMapping("/t.do")
@ResponseBody
public Object t(){
return sessionService.get()+"
"+this.toString();
}