首先,写一个随服务器启动的Servlet,Servlet中定义一个类变量,并定义set方法。随便在set方法中向控制台输出些东西,然后在doGet,doPost或service方法中调用该类对象的一个方法。配置好配置文件,启动服务器。仔细观察控制台,我们发现Servlet启动过程中已经执行了set方法,说明改servlet已经被成功注入。我们再打开浏览器访问下这个Servlet,发现服务器报了空指针异常。大体意思是说你在doGet或doPost或service方法中调用的那个变量是空。为什么会这样?其实也不难理解,我们使用spring的目的就是为了让spring为我们来提供一个已经被注入好的一个实例。而servlet是不同的,servlet是有生命周期的,而这个并不归属spring管理,而是由web容器管理的。那么当servlet刚刚创建的时候,spring可以为servlet注入,当你访问的时候,由于servlet是单实例多线程的,所以,servlet信息被重置,刚刚被注入的对象又为null了。 那么该怎么处理这个问题呢?其实也不难,只要我在获得Serlet的时候,用从Spring获得,而不是由web容器获得就可以了。要想获得Spring中管理的bean肯定要获得ApplicationContext对象,前面说过,在web开发中要获得ApplicationContext对象需要获得ServletContext,所以,需要有一个Servlet,而这个Servlet所要做的就是获得Spring中定义的那个Servlet。而Servlet最终还是要归web容器管理的,所以要归还给web容器,简单的讲就是在定义的这个Servlet中所有方法都用从Spring定义中的获得的那个Servlet去处理就可以了。所以,这个Servlet我们可以写成:
public class ServletToBeanProxy extends GenericServlet {
private String targetBean;
private Servlet proxy;
public void init() throws ServletException {
System.out.println("proxy init");
this.targetBean = getInitParameter("targetBean");
getServletBean();
proxy.init(getServletConfig());
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
proxy.service(req, res);
}
private void getServletBean() {
// ---------- Linstner版 ------------ //
// WebApplicationContext wac = //
// WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
// // this.proxy = (Servlet)
// wac.getBean(targetBean); //------------
// Servlet版 ------------ ApplicationContext
// context = WebApplicationContextUtils
// .getRequiredWebApplicationContext(this.getServletContext());
// this.proxy = (Servlet)
// context.getBean(targetBean);
// //通过ServletContext获得 //
// ApplicationContext context =
// (ApplicationContext) this //
// .getServletContext() //
// .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
// }
}
}
web.xml可以做如下配置:ProxyBean com.up72.servlet.ServletToBeanProxy targetBeanactionServlet1ProxyBean*.do其中init-param中的targetBean就是你在Spring中配置的那个Servlet。 其他的J2EE API的注入网上都有配置方法,有兴趣的可以去查找。我就不列举了。之所以讲Servlet是因为在MVC中Servlet充当了控制器的角色,是MVC的关键和核心。在Servlet往往需要大量注入service层的一些类,然后在类中调用。虽然,配置好Listener或是Servlet以后,你可以通过ServletContext的getAttribute获得Application对象,然后调用getBean()方法获得你所需要的bean,不过,这样就写死了。违背了软件开发的可修改原则。 备注:如果你只需要Spring的注入功能,那么你只需要两个jar包就可以了。spring.jar和commons-logging.jar