Spring容器启动后注入service到Servlet并自动执行

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

找到的解决办法如下:

1、自定义一个用于代理启动Servlet的类DelegatingServletProxy:

package cn.edu.swu.oa.common.util;

import java.io.IOException;

import javax.servlet.GenericServlet;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class DelegatingServletProxy extends GenericServlet {

	private String targetBean;
	private Servlet proxy;

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		proxy.service(arg0, arg1);
	}

	@Override
	public void init() throws ServletException {
		this.targetBean = getServletName();
		getServletBean();
		proxy.init(getServletConfig());
	}

	private void getServletBean() {
		WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
		this.proxy = (Servlet)wac.getBean(targetBean);
	}

}

2、编写启动Servlet:

package cn.edu.swu.oa.common.util;

import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;

import cn.edu.swu.oa.agency.model.Department;
import cn.edu.swu.oa.agency.model.Group;
import cn.edu.swu.oa.agency.service.DepService;
import cn.edu.swu.oa.agency.service.GroService;
import cn.edu.swu.oa.common.model.SysCode;
import cn.edu.swu.oa.safe.model.User;
import cn.edu.swu.oa.safe.service.UserService;

/**
 *
 * 工程:WebOA
 * 类型解释:Spring启动完成后执行初始化操作
 * 类型表述:预读某些实体的Key-Value,放入map,方便以后使用
 * @author ChenGuanwei
 * @version 创建时间:2010-3-25 下午10:55:44
 *
 */
@Component("initialServlet")
public class InitialServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	@Resource
	private UserService userService;

	@Resource
	private DepService depService;

	@Resource
	private GroService groService;

    /**
     * @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);
		}
		//初始化depMap
		List<Department> deps = depService.getAllDeps();
		for(int i = 0; i < deps.size(); i++) {
			Department dep = deps.get(i);
			Integer depId = dep.getDepId();
			String depName = dep.getDepName();
			SysCode.depMap.put(depId, depName);
		}
		//初始化groMap
		List<Group> gros = groService.getAllGroups();
		for(int i = 0; i < gros.size(); i++) {
			Group gro = gros.get(i);
			Integer groId = gro.getGroId();
			String groName = gro.getGroName();
			SysCode.groMap.put(groId, groName);
		}
	}

}

在web.xml文件中配置InitialServlet :
<servlet>
    <description></description>
    <display-name>InitialServlet</display-name>
    <servlet-name>initialServlet</servlet-name>
    <servlet-class>cn.edu.swu.oa.common.util.

DelegatingServletProxy

</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>initialServlet</servlet-name>
    <url-pattern>/InitialServlet</url-pattern>
  </servlet-mapping>

完成这些操作后,就可以在Spring容器启动后执行自定义的Servlet,并且在自定义Servlet中可以使用Spring Annotation的自动注入功能。

备注:需要在xml里面配置compont扫描:示例

<context:component-scan base-package="com.et59.cus"/>

声明: 本文采用 
BY-NC-SA 协议进行授权. 转载请注明转自: 
Spring容器启动后注入service到Servlet并自动执行

标签: 
servlet
spring

时间: 2024-11-03 21:06:40

Spring容器启动后注入service到Servlet并自动执行的相关文章

@EnableAsync annotation metadata was not injected Spring容器启动后访问Servlet报错

@EnableAsync annotation metadata was not injected 2015年12月20日 20:06:54 7570 在初始化spring事务部分碰到该错误, 详细错误信息如下: [plain] view plain copy 警告: Exception encountered during context initialization - cancelling refresh attempt org.springframework.beans.factory.

spring容器启动之我见

spring容器启动之我见. 本人也是自己看看源码,然后方便以后自己记忆和理解,故写此文章,如果有什么错的地方还请大家提出. 针对于tomcat做服务器的项目,我们首先看的就是web.xml文件,spring容器启动去加载监听器 看如下代码:其监听器使用spring api中的类ContextLoaderListener <context-param> <param-name>contextConfigLocation</param-name> <param-va

在非Spring容器中使用注入

在做项目的时候,往往有很多情况是会在非Spring的容器下需要用到Spring管理的组件的,比如说:定时器,servlet,拦截器等等,在这种情况下通常都想使用数据库操作的时候都会感觉到乏力,因为在这种环境下,你要调用相关的Dao层的东西,往往想用依赖注入来实现,卻每每跑出来的就都是空指针异常. 举个例子说明: public class TaskManager implements ServletContextListener { // 每天的毫秒数 public static final lo

Spring框架笔记(三)——Spring容器、属性注入和构造器注入详解

Spring 容器 在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用. Spring 提供了两种类型的 IOC 容器实现. BeanFactory: IOC 容器的基本实现. ApplicationContext: 提供了更多的高级特性. 是 BeanFactory 的子接口. BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身: Appli

spring容器启动之我见(四)

1.我们经常会发现在我们的service中有注解而在dao上没有注解 看图 因为我们在spring容器初始化bean的时候,是把service当做一个bean ,而dao并不是一个bean,这是个人理解,如果有错误,欢迎大家指出. 2. 那我们总结一下那些算是spring 的bean吧. 直接看下面   在类的上面 添加了如下四个注解的我们都看作是spring的bean. @Component.@Repository @Service.@Controller 看字面含义,很容易却别出其中三个:

spring容器启动的加载过程(二)

第六步: public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean { protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory();//具体实现调用子类容器的ref

spring容器启动原理分析1

在项目的web.xml中配置 1 <listener> 2 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 3 </listener> 此配置为spring容器加载入口,因为其javax.servlet.ServletContextListener接口. 下面代码为ServletContextListener的源码: public i

spring容器启动的加载过程

使用spring,我们在web.xml都会配置ContextLoaderListener <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> public class ContextLoaderListener extends ContextLoader implements Servle

Spring容器启动过程

搞了一年多的Java了,每个项目都在用Spring,这几天没事看了看Spring源码,总结了下Spring容器的启动过程,想把它记录下来,免得忘了 spring容器的启动方式有两种: 1.自己提供ApplicationContext自己创建Spring容器 2.Web项目中在web.xml中配置监听启动 org.springframework.web.context.ContextLoaderListener 先介绍第一种(自创建) ClassPathXmlApplicationContext