我提到了一篇非常有用的上一篇文章,但在 ServletContextListener 中注入 bean 时遇到了不同的问题
聆听者
package sapphire.social.connector.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.web.context.support.WebApplicationContextUtils;
import sapphire.adapter.youtube.YTConnectorMgr;
import sapphire.social.connector.logger.LogManager;
public class AppServletContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
if (LogManager.isDebugOn()) {
LogManager
.debug("AppServletContextListener ::: contextDestroyed :::");
}
}
@Override
public void contextInitialized(ServletContextEvent initializingEvent) {
// TODO Auto-generated method stub
if (LogManager.isDebugOn()) {
LogManager
.debug("AppServletContextListener ::: contextInitialized :::");
}
if (LogManager.isDebugOn()) {
LogManager
.debug("AppServletContextListener ::: contextInitialized ::: WebApplicationApplicationContext : "
+ WebApplicationContextUtils
.getWebApplicationContext(initializingEvent
.getServletContext()));
}
if (LogManager.isDebugOn()) {
LogManager
.debug("AppServletContextListener ::: contextInitialized ::: RequiredWebApplicationApplicationContext : "
+ WebApplicationContextUtils
.getRequiredWebApplicationContext(initializingEvent
.getServletContext()));
}
YTConnectorMgr ytConnectorMgr = (YTConnectorMgr) WebApplicationContextUtils
.getWebApplicationContext(initializingEvent.getServletContext())
.getAutowireCapableBeanFactory()
.autowire(YTConnectorMgr.class,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
if (LogManager.isDebugOn()) {
LogManager
.debug("AppServletContextListener ::: contextInitialized ::: ytConnectorMgr : "
+ ytConnectorMgr);
}
}
}
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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
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">
<!-- <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/sapphire-security.xml</param-value>
</context-param> -->
<listener>
<listener-class>sapphire.social.connector.listener.AppServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>central-config</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>central-config</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
中央配置-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="sapphire" />
<mvc:annotation-driven />
<!-- Start : To by-pass MVC view resolution and pass the response to appropriate
media type view resolvers/views Deprecated approach since Spring 3.2.x -->
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="favorPathExtension" value="false"></property>
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="text/xml" />
<entry key="htm" value="text/html" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<!-- <property name="defaultContentType" value="application/json" /> <property
name="defaultViews"> <list> <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"
/> </list> </property> -->
</bean>
<!-- End : To by-pass MVC view resolution and pass the response to appropriate
media type view resolvers/views Deprecated approach since Spring 3.2.x -->
<task:scheduler id="scheduler" pool-size="5" />
<task:annotation-driven scheduler="scheduler" />
</beans>
我试图检索 WebApplicationContext 和 Required WebApplicationContext - 前者为空,后者需要一个 ContextLoaderListener
Fri Nov 15 12:05:55 IST 2013 [Thread-2] AppServletContextListener ::: contextInitialized :::
Nov 15, 2013 12:05:55 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class sapphire.social.connector.listener.AppServletContextListener
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
at org.springframework.web.context.support.WebApplicationContextUtils.getRequiredWebApplicationContext(WebApplicationContextUtils.java:84)
at sapphire.social.connector.listener.AppServletContextListener.contextInitialized(AppServletContextListener.java:44)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Nov 15, 2013 12:05:55 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
Nov 15, 2013 12:05:55 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/Sapphire] startup failed due to previous errors
Fri Nov 15 12:05:55 IST 2013 [Thread-2] AppServletContextListener ::: contextInitialized ::: WebApplicationApplicationContext : null
Fri Nov 15 12:05:55 IST 2013 [stop children - Catalina:j2eeType=WebModule,name=//tenantarchtst.lntinfotech.com/Sapphire,J2EEApplication=none,J2EEServer=none] AppServletContextListener ::: contextDestroyed :::
Nov 15, 2013 12:05:55 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8081"]
Nov 15, 2013 12:05:55 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8010"]
Nov 15, 2013 12:05:55 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 15184 ms
仅供参考,给出我想在 ServletContextListener 中注入的 bean:
@Component(value = "YTConnectorMgr")
public class YTConnectorMgr extends ConnectorMgr {
private static int maxWorkerThreads = 5;
public YTConnectorMgr(int maxWorkerThreads, ConnectorType connectorType) {
super(maxWorkerThreads, connectorType);
}
}
我有一个由 DispatcherServlet 处理的单个配置 xml 文件——理想情况下,我不需要 ContextLoaderListener!但即使是之前的这篇文章也规定了使用 ContextLoaderListener。正如 M.Deinum 所指出的,我不应该复制我的豆子!