@ManagedBean
является устаревшим , поэтому я использовал рекомендованную замену CDI @Named
с ее javax.faces.view.ViewScoped
аннотацией (не JSF javax.faces.bean.ViewScoped
) .
ПРОБЛЕМА
Бин ведет себя как @ApplicationScoped
, то есть @PostConstruct
вызывается , вызывается при развертывании приложения , а затем никогда не вызывается снова т.е. я не вижу @PostConstruct
вызов при посещении страницы / обновить.
Если я вернусь к аннотациям JSF, т.е. @ManagedBean
+ javax.faces.bean.ViewScoped
bean работает как положено .
Я также пытался @Named
+ org.omnifaces.cdi.ViewScoped
, как указано в Как заменить @ManagedBean / @ViewScope на CDI в JSF 2.0 / 2.1 , но результат был таким же, как с javax.faces.view.ViewScoped
(OmniFaces 2.6.2).
КОРОТКО ДОЛГОЙ ИСТОРИИ
Это проблема интеграции JSF + Spring (4.3.1.RELEASE).
Подробнее 1049 *
Приложение работает на Wildfly 11.0.0 .
- specTitle : JSR-000344: API JavaServer (TM) Faces 2.2
- specVersion : 2,2
- specVendor : Oracle
- implTitle : API JavaServer (TM) Faces 2.2
- implVersion : 2.2.13 implVendor: JBoss by Red Hat
Bean
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import java.io.Serializable;
@Named
@ViewScoped
public class TestBean implements Serializable {
private String text;
@PostConstruct
private void onPostConstruct() { /* ... */ }
public void init() { /* ... */ }
public void onCommandButton() { /* ... */ }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
public String getOutput() { return text; }
}
Просмотр (PrimeFaces 6.0.18)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<f:event type="preRenderComponent" listener="#{testBean.init}"/>
<h:form id="form">
<p:inputText id="text" value="#{testBean.text}"/>
<h:outputText id="output" value="#{testBean.output}" />
<p:commandButton value="SUBMIT"
action="#{testBean.onCommandButton}"
update="output"/>
</h:form>
</h:body>
</html>
EDIT
После Kukeltje я рассмотрел стек вызовов создания бина. Каким-то образом Spring управляет созданием бобов . Это трассировка стека, если я сгенерирую исключение из конструктора TestBean
.
Constructor threw exception; nested exception is java.lang.RuntimeException: TestBean
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1105)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1050)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:187)
at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:205)
at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:174)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1508)
at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:239)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:99)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Constructor threw exception; nested exception is java.lang.RuntimeException: TestBean
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:159)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1098)
... 33 more
Я проверил конфиги и нашел регистрацию пользовательской реализации Spring @Scope("view")
(что-то похожее на this , но без обработки обратных вызовов), которая используется в bean-компонентах проекта (@Controller
+ @Scope("view")
- вероятно, плохой дизайн ). Я думаю, что это не имеет никакого отношения к данной проблеме, но для полноты, вот как выглядит applicationContext.xhtml
:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<context:annotation-config/>
<context:property-placeholder location="classpath*:application.properties" ignore-unresolvable="true"/>
<context:property-placeholder location="classpath*:versionInfo.properties"/>
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="view">
<bean class="path.to.custom.ViewScope"/>
</entry>
</map>
</property>
</bean>
</beans>
Вероятно, это корень проблемы:
@Configuration
@ComponentScan(basePackages = "path.to.beans.base.package")
@ImportResource({"/WEB-INF/hibernate-config.xml", "/WEB-INF/applicationContext.xml"})
@PropertySource(value={"classpath:application.properties"}, ignoreResourceNotFound = true)
@Import( SecurityConfig.class )
public class WebConfig {
// nothing more...
}
Кажется, что Spring CDI конфликтует с CDI приложения. Есть ли у вас предложения, что мне делать?