我正在尝试在Spring MVC-Hybris Application中使用spring应用程序上下文,但是它始终为null.
public class FlexSelector{
protected static final ApplicationContext ctx = Registry.getApplicationContext();
protected static final PropertiesReader getPropertiesReader(){
return (PropertiesReader) ctx.getBean("serviceExtensionPropertiesReader");
}
protected static final SearchRestrictionService getSearchRestrictionService(){
return (SearchRestrictionService) ctx.getBean("searchRestrictionService");
}
protected static final FlexibleSearchService getFlexibleSearchService(){
return (FlexibleSearchService) ctx.getBean("flexibleSearchService");
}
protected static final <T> T getModelByExample(T example) {
return getFlexibleSearchService().getModelByExample(example);
} .....}
并具有此类:
public class CustomerSelector extends FlexSelector {
public final static CustomerModel getCustomerByEmail(String email){
CustomerModel filter = new CustomerModel();
filter.setUid(email);
return getModelByExample(filter);
}
}
我现在的工作是Hybris版本的移植.
当我尝试调用CustomerSelector.GetCustomerByEmail(“ test@gmail.com”)时,将引发异常,因为此类中使用的上下文ctx始终为空.
感谢所有的建议.
问候,
达尼洛
解决方法:
存储对Spring对象的静态引用不是一个好主意,并且几乎总是会导致问题.真正的问题不只是存储对Spring对象的引用,而是在类加载时将其分配给静态变量.这是发生了什么:
protected static final ApplicationContext ctx = Registry.getApplicationContext();
这是FlexSelector类中的静态字段,因此在由类加载器加载类时会对其进行初始化.假设到此时,Spring上下文已准备好为您提供正确的引用,这确实很危险.始终获取null实际上是一个很好的结果.可能更糟,当尝试获取所需的bean时,在Spring层中偶尔发生Exception时,可能导致间歇性(!)NoClassDefFoundError -s.因为您没有加载特定的bean,所以上下文本身至少带有一个常量null,这是很好的.
可能的解决方案:
>您应该没有理由持有对ApplicationContext的静态引用.每次使用时都要获取它,它将很好用.
>如果必须这样做,至少要懒惰地购买它.在某些情况下,它仍然可以工作,尽管它仍然不是最好的主意.如果这样做,您只需要声明ctx变量为非最终变量,然后始终通过getter访问它即可.如果尚未初始化,则在首次尝试获取时对其进行初始化.这几乎不需要更改代码,但是我仍然会选择第一种方法.