@Autowired在ServletContextListener中

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有什么问题?

Eri*_* B. 9

当我遇到同样的问题时,我想到了几个想法.

第一个是使用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描述符中定义的监听器在注释定义的监听器之前加载).


Sot*_*lis 5

通过声明

<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非常复杂的自定义实现。您真的不需要自己直接实现它。这个想法保持不变,只是在继承层次结构中更深入。