文档章节

Spring在Listener中注入bean的问题

蜡笔小小小新
 蜡笔小小小新
发布于 2016/10/04 19:33
字数 559
阅读 112
收藏 2
点赞 0
评论 0

下面是我第一次这么干的时候:

package com.lin.warehouse.listener;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;

import com.lin.warehouse.service.IWarehouseService;
import com.lin.warehouse.service.impl.WarehouseServiceImpl;

@WebListener
public class TestListener implements HttpSessionListener {
	
	@Autowired
	private IWarehouseService warehouseService;

    public void sessionCreated(HttpSessionEvent event)  { 
    	
    	System.out.println("----------------------------------------------------->"+warehouseService.getClass().toString());
    }

    public void sessionDestroyed(HttpSessionEvent event)  { 
    }
	
}

在一个Listsner中把接口的实例注入进来,但这样得不到接口的实例,接口引用是空指针。为什么会这样呢?因为Listsner是由Tomcat管理的,Tomcat无法把SpringIOC容器的Bean诸如到Listsner,而注入Bean的工作是由Spring负责的。那么解决这个问题呢?

Spring容器实现了一个监听ServletContext启动事件的监听器,这个监听器把一个IOC容器在ServletContext启动时放进ServletContext容器当做应用的Bean容器。现在只需要在Listsner中得到这个IOC容器就可以了,看看org.springframework.web.context.ContextLoaderListener的源代码。

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
		if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
			throw new IllegalStateException(
					"Cannot initialize context because there is already a root application context present - " +
					"check whether you have multiple ContextLoader* definitions in your web.xml!");
		}

		Log logger = LogFactory.getLog(ContextLoader.class);
		servletContext.log("Initializing Spring root WebApplicationContext");
		if (logger.isInfoEnabled()) {
			logger.info("Root WebApplicationContext: initialization started");
		}
		long startTime = System.currentTimeMillis();

		try {
			// Store context in local instance variable, to guarantee that
			// it is available on ServletContext shutdown.
			if (this.context == null) {
				this.context = createWebApplicationContext(servletContext);
			}
			if (this.context instanceof ConfigurableWebApplicationContext) {
				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
				if (!cwac.isActive()) {
					// The context has not yet been refreshed -> provide services such as
					// setting the parent context, setting the application context id, etc
					if (cwac.getParent() == null) {
						// The context instance was injected without an explicit parent ->
						// determine parent for root web application context, if any.
						ApplicationContext parent = loadParentContext(servletContext);
						cwac.setParent(parent);
					}
					configureAndRefreshWebApplicationContext(cwac, servletContext);
				}
			}
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

			ClassLoader ccl = Thread.currentThread().getContextClassLoader();
			if (ccl == ContextLoader.class.getClassLoader()) {
				currentContext = this.context;
			}
			else if (ccl != null) {
				currentContextPerThread.put(ccl, this.context);
			}

			if (logger.isDebugEnabled()) {
				logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
						WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
			}
			if (logger.isInfoEnabled()) {
				long elapsedTime = System.currentTimeMillis() - startTime;
				logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
			}

			return this.context;
		}
		catch (RuntimeException ex) {
			logger.error("Context initialization failed", ex);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
			throw ex;
		}
		catch (Error err) {
			logger.error("Context initialization failed", err);
			servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
			throw err;
		}
	}

上面是初始化ServletContext的方法,把IOC容器放进ServletContext容器的是这句,

servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);

它的KEY是 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,那就在Listsner中通getAttribute(“”,);方法得到IOC容器

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;

import com.lin.warehouse.service.IWarehouseService;
import com.lin.warehouse.service.impl.WarehouseServiceImpl;

@WebListener
public class TestListener implements HttpSessionListener {
	
	//@Autowired
	private IWarehouseService warehouseService;

    public void sessionCreated(HttpSessionEvent event)  { 
    	
    	ApplicationContext applicationContext = (WebApplicationContext)event.getSession().getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    	
    	warehouseService = applicationContext.getBean("warehouseService",WarehouseServiceImpl.class );
    }

    public void sessionDestroyed(HttpSessionEvent event)  { 
    }
	
}

 

© 著作权归作者所有

共有 人打赏支持
蜡笔小小小新
粉丝 32
博文 104
码字总数 75210
作品 0
深圳
后端工程师
spring全套,出现bean问题

springmvc datajpa,出现问题 现象: 1.在listener中通过webapplicationcontext获取service层的bean出错(用类型找不到,用名称则类型不对,是个proxy),但是获取dao层的bean就正常。contr...

noday ⋅ 2015/08/09 ⋅ 5

org.springframework.web.context.ContextLoaderListener

常用Web框架SpringMVC及WebX级联容器原理探究 一、前言 使用一个东西最好研究下他的原理,因为如果知其然那么在排查问题时候会很方便,本文则针对常用web框架SpringMVC和集团的WebX框架的容器...

aoper ⋅ 2017/11/14 ⋅ 0

springMvc源码学习之:利用springMVC随时随地获取HttpServletRequest等对象

一、准备工作: 在web.xml中添加 [html]view plain copy org.springframework.web.context.request.RequestContextListener 二、使用方法: 1、方法一:通过代码实现 [java]view plain copy ......

无信不立 ⋅ 2016/09/23 ⋅ 0

Spring - applicationContext.xml的理解

applicationContext.xml是Spring的配置文件,主要是将各种POJO,JAVA,action配置到XML转交给beanfactory管理,降低耦合度 主要的配置组件: <bean id="射影class的名字" class="写的JAVA类"...

Elivense ⋅ 2016/11/25 ⋅ 0

web.xml中的contextConfigLocation在spring中的作用

在web.xml中通过contextConfigLocation配置spring,contextConfigLocation 参数定义了要装入的 Spring 配置文件。 如果想装入多个配置文件,可以在 标记中用逗号作分隔符。 在web.xml里配置L...

architect刘源源 ⋅ 05/04 ⋅ 0

spring配置restful格式url

项目中使用了restful格式的url,发生一个奇怪的问题 当 url格式如: /testController/test/test 是能正常拦截 为 /testController/test 时报302 found错误 web.xml配置 org.springframework....

回忆若风 ⋅ 2015/05/27 ⋅ 1

Spring核心源码:ApplicationContext

废话 spring版本:4.0.6 随便做了这么多年的spring,但是源码就只阅读过 shiro的。一直想去读一下spring,mybatis,netty,这些结构优美的开源框架的源码。 核心包: spring-context:spring的上...

GITTODO ⋅ 04/25 ⋅ 0

浅谈application-*.xml和springmvc-.xml的区别

项目配置说明 一般springMVC和Spring的整合过程中,我们喜欢配置两个文件application-*.xml和springmvc-.xml,但是配置不好的话,很容易出现这样的问题:Injection of resource dependencie...

小车车 ⋅ 2016/07/07 ⋅ 0

详解Java的Spring框架中的注解的用法

使用Spring注解来注入属性 1.1. 使用注解以前我们是怎样注入属性的 类的实现: 配置文件: 1.2. 引入@Autowired注解(不推荐使用,建议使用@Resource) 类的实现(对成员变量进行标注) 或者...

Airship ⋅ 04/22 ⋅ 0

Spring温故而知新 - bean的装配

按条件装配bean 就是当满足特定的条件时Spring容器才创建Bean,Spring中通过@Conditional注解来实现条件化配置bean package com.sl.ioc;import org.springframework.context.annotation.Bean;...

Java-老刘 ⋅ 05/07 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

十五周二次课

十五周二次课 17.1mysql主从介绍 17.2准备工作 17.3配置主 17.4配置从 17.5测试主从同步 17.1mysql主从介绍 MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主...

河图再现 ⋅ 44分钟前 ⋅ 0

docker安装snmp rrdtool环境

以Ubuntu16:04作为基础版本 docker pull ubuntu:16.04 启动一个容器 docker run -d -i -t --name flow_mete ubuntu:16.04 bash 进入容器 docker exec -it flow_mete bash cd ~ 安装基本软件 ......

messud4312 ⋅ 今天 ⋅ 0

OSChina 周一乱弹 —— 快别开心了,你还没有女友呢。

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享吴彤的单曲《好春光》 《好春光》- 吴彤 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :小萝莉街上乱跑,误把我认错成...

小小编辑 ⋅ 今天 ⋅ 7

mysql in action / alter table

change character set ALTER SCHEMA `employees` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci ;ALTER TABLE `employees`.`t2` CHARACTER SET = utf8mb4 , COLLAT......

qwfys ⋅ 今天 ⋅ 0

Java 开发者不容错过的 12 种高效工具

Java 开发者常常都会想办法如何更快地编写 Java 代码,让编程变得更加轻松。目前,市面上涌现出越来越多的高效编程工具。所以,以下总结了一系列工具列表,其中包含了大多数开发人员已经使用...

jason_kiss ⋅ 昨天 ⋅ 0

Linux下php访问远程ms sqlserver

1、安装freetds(略,安装在/opt/local/freetds 下) 2、cd /path/to/php-5.6.36/ 进入PHP源码目录 3、cd ext/mssql进入MSSQL模块源码目录 4、/opt/php/bin/phpize生成编译配置文件 5、 . ./...

wangxuwei ⋅ 昨天 ⋅ 0

如何成为技术专家

文章来源于 -- 时间的朋友 拥有良好的心态。首先要有空杯心态,用欣赏的眼光发现并学习别人的长处,包括但不限于工具的使用,工作方法,解决问题以及规划未来的能力等。向别人学习的同时要注...

长安一梦 ⋅ 昨天 ⋅ 0

Linux vmstat命令实战详解

vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。这个命令是我查看Linux/Unix最喜爱的命令...

刘祖鹏 ⋅ 昨天 ⋅ 0

MySQL

查看表相关命令 - 查看表结构    desc 表名- 查看生成表的SQL    show create table 表名- 查看索引    show index from  表名 使用索引和不使用索引 由于索引是专门用于加...

stars永恒 ⋅ 昨天 ⋅ 0

easyui学习笔记

EasyUI常用控件禁用方法 combobox $("#id").combobox({ disabled: true }); ----- $("#id").combobox({ disabled: false}); validatebox $("#id").attr("readonly", true); ----- $("#id").r......

miaojiangmin ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部