题主用的是SpringMVC,Spring的bean是由IOC容器管理的,所以这个问题的核心是IOC容器初始化bean,首先从SpringMVC的入口DispatcherServlet说起,一图胜千言:
DispatcherServlet在初始化的时候会启动一个web容器,用户可以向这个web容器中注入相关的组件。一般而言,我们在web.xml这样配置ContextLoaderListener:
contextConfigLocation
/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml,/WEB-INF/jason-servlet.xml
org.springframework.web.context.ContextLoaderListener
这时候又会启动一个web容器,该web容器就作为父容器,而DispatcherServlet启动的容器作为子容器。
子容器管理SpringMVC的组件,如Controller,该容器即为一个IOC容器。
下面来讲讲重点,也就是IOC容器是如何初始化并管理bean的,Spring有三种初始化方式:
用构造器来实例化
使用 静态工厂方法实例化
使用实例工厂方法实例化
简单来讲,对于Controller而言,Spring的处理方式是new一个然后使用。所以设置成静态是没必要的,SpringMVC的Controller默认是单例,非线程安全,最佳实践是设计成一个无状态的类。另外题主贴的代码可以改成这样的形式:
@Controller
public class IndexController {
private UserService userService;
@Resources
public void setUserService(UserService userService){
this.userService = userService;
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Map map, HttpServletRequest request, HttpSession session) {
Integer uid = (Integer) session.getAttribute("uid");
User user = userService.get(uid);
map.put("user", user);
return "index";
}
}