Java SystemEventListener+@WebSphere8.5上的值为null
我在一个我实现的SystemEventListener中遇到了一个问题。我正在使用注释@Value从属性文件中注入一个值。问题是注释@Value在应用程序的其他部分(如@Controller)工作正常,但在这个SystemEventListener中工作不正常。它还在tomcat上工作,但在WebSphere8.5上没有 你知道会是什么吗 实施Java SystemEventListener+@WebSphere8.5上的值为null,java,spring,jakarta-ee,websphere,websphere-8,Java,Spring,Jakarta Ee,Websphere,Websphere 8,我在一个我实现的SystemEventListener中遇到了一个问题。我正在使用注释@Value从属性文件中注入一个值。问题是注释@Value在应用程序的其他部分(如@Controller)工作正常,但在这个SystemEventListener中工作不正常。它还在tomcat上工作,但在WebSphere8.5上没有 你知道会是什么吗 实施 public class PreRenderViewListener implements SystemEventListener { @Va
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>
这个配置在Tomcat中运行良好,所以我认为代码中没有问题,可能是与WebSphere8.5相关的问题。我一直在互联网上寻找这个问题,但我没有找到任何像这样的
谢谢你的帮助 正如戴纳姆先生所说
PreRenderViewListener是一个JSF(faces)管理的bean,而不是
spring管理bean,所以@Value不应该工作
因此,为了让它工作,您必须使您的PreRenderViewListener
被Spring“识别”,这意味着它必须是Spring组件。我现在正在使用的一个解决方案(我希望得到评论)是使用
multicaster
,比如org.springframework.web.jsf.DelegatingPhaseListenerMulticaster
,它将在faces配置中注册,并将所有工作委托给实现SystemEventListener
的其他Springbean
下面是Multicast的代码(它的灵感来自于前面提到的Spring Multicast)
最后,创建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);
}
}
我希望这会有所帮助,即使有点晚。我会很惊讶它会起作用,基本上WebSphere中的行为就是我所期望的。
PreRenderViewListener
是一个JSF(faces)管理的bean,而不是spring管理的bean,因此@Value
不应该工作。
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);
}
}
<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>
@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);
}
}