标签:beans splay 目标 自定义 import point void framework xmlns
自定义一个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容器还未启动。
标签:beans splay 目标 自定义 import point void framework xmlns
原文地址:https://www.cnblogs.com/silenceshining/p/12466354.html