abd*_*ady 6 java spring spring-mvc
我hava aclass InitApp
@Component
public class InitApp implements ServletContextListener {
@Autowired
ConfigrationService weatherConfService;
/** Creates a new instance of InitApp */
public InitApp() {
}
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println(weatherConfService);
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
Run Code Online (Sandbox Code Playgroud)
和web.xml中的监听器:
<listener>
<listener-class>com.web.Utils.InitApp</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
confService打印 - > null有什么问题?
当我遇到同样的问题时,我想到了几个想法.
第一个是使用Spring utils从侦听器中的Spring上下文中检索bean:
例如:
@WebListener
public class CacheInitializationListener implements ServletContextListener {
/**
* Initialize the Cache Manager once the application has started
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
CacheManager cacheManager = WebApplicationContextUtils.getRequiredWebApplicationContext(
sce.getServletContext()).getBean(CacheManager.class);
try {
cacheManager.init();
} catch (Exception e) {
// rethrow as a runtime exception
throw new IllegalStateException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只有一个或两个bean,这可以正常工作.否则它会变得单调乏味.另一个选择是显式调用Spring的Autowire实用程序:
@WebListener
public class CacheInitializationListener implements ServletContextListener {
@Autowired
private CacheManager cacheManager;
/**
* Initialize the Cache once the application has started
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
try {
cacheManager.init();
} catch (Exception e) {
// rethrow as a runtime exception
throw new IllegalStateException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
Run Code Online (Sandbox Code Playgroud)
这两个解决方案中的警告是,必须首先加载Spring上下文,然后才能使用其中任何一个.鉴于无法使用定义监听器顺序@WebListener,请确保ContextLoaderListener定义Spring web.xml以强制首先加载它(在Web描述符中定义的监听器在注释定义的监听器之前加载).
通过声明
<listener>
<listener-class>com.web.Utils.InitApp</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
在web.xml中,您要告诉容器初始化并注册的实例InitApp。因此,该对象不受Spring的管理,您也无法对其进行@Autowired任何操作。
如果将您的应用程序上下文设置为对组件进行组件扫描com.web.Utils,则您将拥有InitApp未在容器中注册为Listener 的Bean。因此,即使您的其他bean是@Autowiredservlet容器,它也永远不会实现。
那是权衡。
如果将编程配置与servlet 3.0 ServletContainerInitializer或一起使用时,则有一些解决方法WebApplicationInitializer。您不会使用@Autowired,而只会使用setter / getter来设置实例。
这是一个例子
class SpringExample implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = ...;
SomeBean someBean = context.getBean(SomeBean.class);
CustomListener listener = new CustomListener();
listener.setSomeBean(someBean);
// register the listener instance
servletContext.addListener(listener);
// then register DispatcherServlet and ContextLoaderListener, as appropriate
...
}
}
class CustomListener implements ServletContextListener {
private SomeBean someBean;
public SomeBean getSomeBean() {
return someBean;
}
public void setSomeBean(SomeBean someBean) {
this.someBean = someBean;
}
@Override
public void contextInitialized(ServletContextEvent sce) {
// do something with someBean
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,Spring有一些WebApplicationInitializer非常复杂的自定义实现。您真的不需要自己直接实现它。这个想法保持不变,只是在继承层次结构中更深入。