spring boot在ServletContextListener中获取spring上下文

先说结论,百度上这个问题真的好难查,终于找到一个解决方法

https://blog.csdn.net/u014723529/article/details/51404187

类似文章还有http://kewen1989.iteye.com/blog/1891124


正文

公司项目,之前是用spring,后来要移植到spring boot


项目中有一个通过ApplicatonContextAware获取spring上下文的类

@Component
public class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext ctx = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ctx = applicationContext;
    }

    public static ApplicationContext getSpringContext(){
        return ctx;
    }

}


还有一个ServletContextListener,在AListener中使用SpringContextHolder获取ApplicationContext,从而去getBean

@Component
public class AListener implements ServletContextListener{
    
    public void contextInitialized(ServletContextEvent sce) {
        SpringContextHolder.getSpringContext.getBean("TestBean");
    }

    
public void contextInitialized(ServletContextEvent sce) {}
}

原spring项目中web.xml配置如下

<!-- 设置Spring监听器 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        classpath:applicationContext.xml,
        classpath:applicationContext-*
    </param-value>
</context-param>

<listener>
    <listener-class>........AListener</listener-class>
</listener>


按web.xml配置顺序应该是先加载ContextLoaderListener,此时spring会自动去调用SpringContextHolder的setApplicationContext方法。随后调用AListener


但是移植到spring boot之后,通过@ServletComponentScan,或者在入口函数下面通过@Bean向spring注册bean,都会先加载AListener后在SpringContextHolder中设置上下文


debug了一下源码,在AbstractApplicationContext.java中refresh()中registerListeners()会启动内置tomcat容器,启动tomcat时会初始化AListener,然后在finishBeanFactoryInitialization(beanFactory)为SpringContextAware设置上下文。

所以难道这个顺序在spring boot里面是死的吗?spring+tomcat是tomcat容器去加载spring,spring boot好像是spring boot框架去加载tomcat

暂时这个问题还要再研究


不过倒是找到了在AListener中获取SpringContext的方法,即文章开头链接中的方法

public void contextInitialized(ServletContextEvent event) {  
        app = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext()); 
        app.getBean("UserService");   
    }  

猜你喜欢

转载自blog.csdn.net/songduo22/article/details/80112988