首页 > 编程语言 > 详细

listener中获取spring中管理的bean

时间:2020-03-11 23:24:30      阅读:80      评论:0      收藏:0      [点我收藏+]

看第一个例子:

自定义一个listener:

package com.test.common.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.beans.factory.annotation.Autowired;

import com.test.moudules.test.service.MyService;

public class CustomListener implements ServletContextListener {
    
    @Autowired
    MyService myService;

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("*****started*******");
        myService.test();
    }

}

在web.xml中进行配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>testWeb</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
     <listener>
        <listener-class>com.test.common.listener.CustomListener</listener-class>
    </listener>
<!-- springmvc 前端控制器 -->
    <servlet>
        <servlet-name>dispatcherSerlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherSerlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

 

MyService(纳入spring管理的普通bean):

package com.test.moudules.test.service;

import org.springframework.stereotype.Component;

@Component
public class MyService {

    public void test() {
        System.out.println("this is test method");
    }
}

启动web应用结果:

java.lang.NullPointerException
    at com.test.common.listener.CustomListener.contextInitialized(CustomListener.java:22)

分析原因:

listener(以及filter)是由servlet容器(比如tomcat)来进行管理的,而像MyService这些bean是由spring容器管理的,所以在CustomListener中是识别不了自动注入的注解(@Autowired),也无法获取到spring容器中的MyService这些bean的,所以报空指针异常。

看第二个例子:

package com.test.common.listener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

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

import com.test.moudules.test.service.MyService;

public class CustomListener implements ServletContextListener {

    MyService myService;

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }

//servlet容器启动时执行的方法
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("*****started*******");
        myService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext())
                .getBean(MyService.class);
        myService.test();
    }

}

 

启动web应用结果:

*****started*******
this is test method

分析原因:看结果是执行成功了拿到了MyService的bean,并执行了方法。如何实现呢?我们最终的目标是要拿到spring管理的bean(像MyServlce这些类的实现),可以通过

web.xml中配置的DispatcherServlet,DispatcherServlet加载时会启动一个spring容器(作为子容器),而像管理MyService这些bean的spring容器是父容器,通过

WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext())可以在子容器中拿到父容器的applicationContext,进而拿到相关的bean。

注意:

配置顺序必须如下:

 <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
     <listener>
        <listener-class>com.test.common.listener.CustomListener</listener-class>
    </listener>

即让父spring容器先启动起来,再启动自定义的listener若顺序返了肯定也拿不到相应的bean,因为父spring容器还未启动。

 

 

listener中获取spring中管理的bean

原文:https://www.cnblogs.com/silenceshining/p/12466354.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!