通常做法是定义一个Servlet,并在web.xml中配置Servlet的启动顺序<load-on-startup>的值在DispatcherServlet之后。但这样做的缺点是在Servlet中无法使用Spring的依赖注入功能,只能使用WebApplicationContext的getBean()方法获取bean。


找到的解决办法如下:
1、自定义一个用于代理启动Servlet的类DelegatingServletProxy:
package com.xxxx;


import java.io.IOException;  
  
import javax.servlet.Servlet;  
import javax.servlet.ServletContext;  
import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
  
import org.springframework.web.context.WebApplicationContext;  
import org.springframework.web.context.support.WebApplicationContextUtils;  
  
public class DelegatingServletProxy extends HttpServlet {  
    private static final long serialVersionUID = 1L;  
    private String targetServletBean;  
    private Servlet proxy;  
      
    @Override  
    public void init() throws ServletException {  
        this.targetServletBean = this.getInitParameter("targetServletBean");  
        this.getServletBean();  
        this.proxy.init(this.getServletConfig());  
    }  
  
    @Override  
    protected void service(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        proxy.service(request,response);   
    }  
  
    private void getServletBean(){  
        ServletContext servletContext = this.getServletContext();  
        WebApplicationContext wac = null;   
        wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);  
        this.proxy = (Servlet) wac.getBean(targetServletBean);  
    }  
}  


2、不同于一般的 Servlet 在 web.xml 中的配置,需要配置的是 Servlet 代理类,而非 Servlet:
<servlet>  
    <servlet-name>proxyServletBean</servlet-name>  
    <servlet-class>com.xxxx.DelegatingServletProxy</servlet-class>  
    <init-param>  
        <param-name>targetServletBean</param-name>  
        <param-value>myBean</param-value>  
    </init-param>  
    <load-on-startup>2</load-on-startup>
</servlet>      
<servlet-mapping>  
    <servlet-name>proxyServletBean</servlet-name>  
    <url-pattern>/file</url-pattern>  
</servlet-mapping>  

3、用spring bean的方式定义名字是myBean的servlet。如同一般的 Servlet 我们的这个 MyServlet 需要继承 GenericServlet 或者 HttpServlet:
@Component("myBean")
public class MyServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	@Resource
	private UserService userService;
	
	
    /**
     * @see HttpServlet#HttpServlet()
     */
    public InitialServlet() {
        super();
    }
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
	}
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}
	@Override
	public void init(ServletConfig config) throws ServletException {
		//初始化eserMap
		List<User> users = userService.getUsers();
		for(int i = 0; i < users.size(); i++) {
			User user = users.get(i);
			Integer userId = user.getUserId();
			String userName = user.getUserName();
			SysCode.userMap.put(userId, userName);
		}
	}
}


4、如果是多个 Servlet 的话,可以共用同一个代理 Servlet。Servlet 代码和代理 Servlet 代码无须改变,只需要注意一下在 web.xml 里的配置即可:
<servlet>  
    <servlet-name>proxyServletBean2</servlet-name>  
    <servlet-class>com.xxxx.DelegatingServletProxy</servlet-class>  
    <init-param>  
        <param-name>targetServletBean</param-name>  
        <param-value>myBean2</param-value>  
    </init-param>  
</servlet>      
<servlet-mapping>  
    <servlet-name>proxyServletBean2</servlet-name>  
    <url-pattern>/file2</url-pattern>  
</servlet-mapping>      
  
<servlet>  
    <servlet-name>proxyServletBean3</servlet-name>  
    <servlet-class>com.xxxx.DelegatingServletProxy</servlet-class>  
    <init-param>  
        <param-name>targetServletBean</param-name>  
        <param-value>myBean3</param-value>  
    </init-param>  
</servlet>      
<servlet-mapping>  
    <servlet-name>proxyServletBean3</servlet-name>  
    <url-pattern>/WebService</url-pattern>  
</servlet-mapping>      


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐