Spring 上下文未加载

Spring Context not loaded

我正在尝试将我的一个旧项目从 Spring 3.0.3.RELEASE 迁移到 4.0.9.RELEASE。我将 pom.xml 依赖项更改为 4.0.9,从那一刻起我就遇到了问题。 DispatcherServlet 无法在应用程序上下文中找到 bean。

以下是我的文件

web.xml

<context-param>
    <param-name>bootstrapConfig</param-name>
    <param-value>
        /com/core/choreographer/bootstrap/bootstrap-config.xml
    </param-value>
</context-param>

<listener>
    <listener-class>
        com.core.bootstrap.BootstrapManager
    </listener-class>
</listener>

<listener>
    <listener-class>com.spring.http.SpringHttpContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>http-remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:com/remote/springhttp-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>http-remoting</servlet-name>
    <url-pattern>/remoting/*</url-pattern>
</servlet-mapping>

bootstrap-config.xml 具有要插入到 spring 上下文中的所有 bean。它由 BootstrapManager 读取,是 ServletContextListener 的子项,并插入到 spring 上下文中。如下

public class BootstrapManager implements ServletContextListener
{
    public void contextInitialized( ServletContextEvent ctxEvt )
    {
        URL cfgURL = "location to the xml file" ;
        ServletContext context = ctxEvt.getServletContext() ;
        bootstrap.initialize( cfgURL ) ;
    }
}

public class Bootstrap
{
    public void initialize( final URL cfgURL ) throws BootstrapException
    {
        XMLConfiguration config = new XMLConfiguration() ;
        URL dtdURL = ReflectionUtil.getResource( Bootstrap.class, "bootstrap-config.dtd" ) ;

        // register it at the configuration
        config.registerEntityId( "-//Bootstrap//DTD 1.0//EN", dtdURL ) ;
        config.setValidating( true ) ;
        config.setURL( cfgURL ) ;
        config.load() ;
        initBootstrapElements( config ) ;
    }
    private void initBootstrapElements( final XMLConfiguration config ) throws BootstrapException
    {
        HierarchicalConfiguration cfg = null ;
        int numElements = config.getList( "bootstrap-element[@class]"     ).size() ;
        for( int i = 0 ; i < numElements ; i++ )
        {
            cfg = config.configurationAt( "bootstrap-element(" + i + ")" ) ;
            initElement( cfg ) ;
        }
    }
    public void initElement( final HierarchicalConfiguration config ) throws BootstrapException
    {
        String className = null ;
        String propName = null ;
        Object propVal = null ;
        HierarchicalConfiguration propCfg = null ;
        BootstrapElement element = null ;

        className = config.getString( "[@class]" ) ;
        element = (BootstrapElement) ReflectionUtil.createInstance( className.trim() ) ;

        beanWrapper.setWrappedInstance( element ) ;
        int numProps = config.getList( "property[@name]" ).size() ;
        for( int i = 0 ; i < numProps ; i++ )
        {
            propCfg = config.configurationAt( "property(" + i + ")" ) ;
            propName = propCfg.getString( "[@name]" ) ;
            propVal = propCfg.getProperty( "[@value]" ) ;
            if( propVal == null )
            {
                propVal = propCfg.getList( "value" ) ;
            }
            beanWrapper.setPropertyValue( propName, propVal ) ;
        }

        element.initialize() ;//This called the below new ClassPathXmlApplicationContext(
    }
}

ClassPathXmlApplicationContext appCtx = new ClassPathXmlApplicationContext( (String []) cfgLocations.toArray( new String [ 0 ] ) ) ;

然后我有一个 ContextLoaderListener

public class SpringHttpContextLoaderListener extends ContextLoaderListener {

    private ContextLoader loader;

    protected ContextLoader createContextLoader() {
        loader = new SpringHttpContextLoader();
        return loader;
    }

    public ContextLoader getContextLoader(){
        return loader;
    }

}

这是上下文加载器

public class SpringHttpContextLoader extends ContextLoader {

    protected ApplicationContext loadParentContext(ServletContext servletContext)
            throws BeansException {
        SpringObjectFactory fact = BaseSpringObjectFactory.getInstance();
        return fact.getApplicationContext();
    }

}

这一切在 Spring 3.0.3 中都运行良好。当我试图将所有 Jar 替换为 4.0.9 时。 springhttp-servlet.xml 中定义的 Beans 无法找到 bootstrap-config.xml.[=15= 中定义的 bean ]

非常感谢任何建议。过去 2-3 周以来,我一直被困在这个问题上。

我发现了 SpringHttpContextLoaderListener 的问题。它覆盖了 createContextLoadergetContextLoader 的方法 deprecated in Spring version 3 所以被删除了在 Spring 版本 4 中。因此,自定义上下文未作为父上下文加载。

public class SpringHttpContextLoaderListener extends ContextLoaderListener {

    private ContextLoader loader;

    protected ContextLoader createContextLoader() {
        loader = new SpringHttpContextLoader();
        return loader;
    }

    public ContextLoader getContextLoader(){
        return loader;
    }

}

解决方案 在 class SpringHttpContextLoaderListener

中覆盖 class ContextLoaderloadParentContext
protected ApplicationContext loadParentContext(ServletContext servletContext)
        throws BeansException {
    SpringObjectFactory fact = BaseSpringObjectFactory.getInstance();
    return fact.getApplicationContext();
}

这会将自定义创建的 Context 设置为父级,并将对所有 child context

可用

如果您要迁移到 spring 4,则无需执行其中大部分操作。当 AbstractAnnotationConfigDispatcherServletInitializer 加载上下文 spring 和应用程序上下文时。