我正在尝试将我的旧项目从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周内陷入困境。
答案 0 :(得分:1)
我发现问题与SpringHttpContextLoaderListener
有关。它覆盖了 Spring版本3 中已弃用的方法createContextLoader
和getContextLoader
,因此在 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加载上下文弹簧和应用程序上下文。