[英]SystemEventListener + @Value null on Websphere 8.5
我在實現的一個SystemEventListener中面臨一個問題。 我正在使用注釋@Value從屬性文件中注入值。 問題是注釋@Value在應用程序的其他部分(例如@Controller)中運行良好,但在此SystemEventListener中運行不正常。 它也可以在tomcat上運行,但不能在Websphere 8.5上運行。
你知道會是什么嗎?
實作
public class PreRenderViewListener implements SystemEventListener {
@Value("${path}/fileName.properties")
private String filePath;
faces-config.xml
<system-event-listener>
<system-event-listener-class>com.package.PreRenderViewListener</system-event-listener-class>
<system-event-class>javax.faces.event.PreRenderViewEvent</system-event-class>
</system-event-listener>
解析器是一個擴展了PropertyPlaceholderConfigurer
類的Bean,該類運行良好。
<bean id="uxMasterConfigBean" class="com.csc.cscip.ux.common.util.UXPropertiesConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:/resources/master/ux.default.configuration.properties</value>
<value>${ux.master.configuration.file.path}</value>
</list>
</property>
</bean>
此配置在Tomcat中運行良好,因此我認為這不是代碼中的問題,也許與Websphere 8.5有關。 我一直在互聯網上尋找此問題,但沒有找到類似的東西。
謝謝你的幫助!
正如Deinum先生所說,
PreRenderViewListener是JSF(面部)托管的bean,而不是spring托管的bean,因此@Value不起作用。
因此,要使其正常工作,必須使Spring“識別” PreRenderViewListener
,這意味着它必須是Spring組件。
我現在正在使用的一個解決方案(我希望對此發表評論)是使用諸如org.springframework.web.jsf.DelegatingPhaseListenerMulticaster
類的multicaster
器,該multicaster
將在faces配置中注冊並將所有工作委托給其他Spring Bean。實現SystemEventListener
。
這是多播器的代碼(它受上述Spring多播器的啟發)。
package org.example.listeners;
import java.util.Collection;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;
public class DelegatingSystemEventListenerMulticaster implements SystemEventListener{
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
for (SystemEventListener listener : getDelegates(FacesContext.getCurrentInstance())) {
if(listener.isListenerForSource(event.getSource())){
listener.processEvent(event);
}
}
}
@Override
public boolean isListenerForSource(Object source) {
for (SystemEventListener listener : getDelegates(FacesContext.getCurrentInstance())) {
if(listener.isListenerForSource(source)){
return true;
}
}
return false;
}
/**
* Obtain the delegate PhaseListener beans from the Spring root WebApplicationContext.
* @param facesContext the current JSF context
* @return a Collection of PhaseListener objects
* @see #getBeanFactory
* @see org.springframework.beans.factory.ListableBeanFactory#getBeansOfType(Class)
*/
protected Collection<SystemEventListener> getDelegates(FacesContext facesContext) {
ListableBeanFactory bf = getBeanFactory(facesContext);
return BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, SystemEventListener.class, true, false).values();
}
/**
* Retrieve the Spring BeanFactory to delegate bean name resolution to.
* <p>The default implementation delegates to {@code getWebApplicationContext}.
* Can be overridden to provide an arbitrary ListableBeanFactory reference to
* resolve against; usually, this will be a full Spring ApplicationContext.
* @param facesContext the current JSF context
* @return the Spring ListableBeanFactory (never {@code null})
* @see #getWebApplicationContext
*/
protected ListableBeanFactory getBeanFactory(FacesContext facesContext) {
return getWebApplicationContext(facesContext);
}
/**
* Retrieve the web application context to delegate bean name resolution to.
* <p>The default implementation delegates to FacesContextUtils.
* @param facesContext the current JSF context
* @return the Spring web application context (never {@code null})
* @see FacesContextUtils#getRequiredWebApplicationContext
*/
protected WebApplicationContext getWebApplicationContext(FacesContext facesContext) {
return FacesContextUtils.getRequiredWebApplicationContext(facesContext);
}
}
在faces-config.xml
:
<system-event-listener>
<system-event-listener-class>org.example.listeners.DelegatingSystemEventListenerMulticaster</system-event-listener-class>
<!--Use any event you want here -->
<system-event-class>javax.faces.event.PostAddToViewEvent</system-event-class>
</system-event-listener>
最后,創建您的SystemEventListener
bean,例如:
@Component
public class FooComponentListener implements SystemEventListener{
@Autowired
private FooService fooService;
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
//Do your business
}
@Override
public boolean isListenerForSource(Object source) {
//Or any other condition
return (source instanceof HtmlInputText || source instanceof HtmlOutputText || source instanceof HtmlOutputLabel);
}
}
我希望這會有所幫助,即使遲了一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.