Spring上下文未加载

时间:2015-05-05 07:33:56

标签: java spring applicationcontext servletcontextlistener

我正在尝试将我的旧项目从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;
    }

}

这是ContextLoader

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中定义的bean。

任何建议都非常感谢。我在过去的2-3周内陷入困境。

2 个答案:

答案 0 :(得分:1)

我发现问题与SpringHttpContextLoaderListener有关。它覆盖了 Spring版本3 已弃用的方法createContextLoadergetContextLoader,因此在 Spring版本4 中删除了>。因此,自定义上下文未作为父上下文加载。

public class SpringHttpContextLoaderListener extends ContextLoaderListener {

    private ContextLoader loader;

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

    public ContextLoader getContextLoader(){
        return loader;
    }

}

<强>解决方案 覆盖课程loadParentContext

中的ContextLoader个课程SpringHttpContextLoaderListener
protected ApplicationContext loadParentContext(ServletContext servletContext)
        throws BeansException {
    SpringObjectFactory fact = BaseSpringObjectFactory.getInstance();
    return fact.getApplicationContext();
}

这会将自定义创建的上下文设置为父级,并且可用于所有子级上下文

答案 1 :(得分:0)

如果您要迁移到第4弹,那么大部分内容都不需要执行。由于AbstractAnnotationConfigDispatcherServletInitializer加载上下文弹簧和应用程序上下文。