如何将 Injected/Autowired 对象从 Spring 传递给 ManagedBean?

How to pass Injected/Autowired object from Spring to ManagedBean?

我正在使用 Spring 和 EJB/Primefaces 进行项目,我想将值从 spring 上下文传递到托管 bean。我将用示例代码进行演示以进一步说明。

假设我们有以下域 class(为了更好的可读性,我保持简单):

public class Store {
    @JsonProperty("store_name")
    private String storeName;

    //constructors, getters and setters...
}

@Json属性 的原因是因为我从另一个应用程序获取此值,该应用程序将 Json POST 到以下控制器:

@Controller
@RequestMapping("/store")
public class StoreController {
    @Autowired
    private Store store;

    @RequestMapping(method = RequestMethod.POST)
    public String getStoreResponse(@RequestBody String store) throws JsonParseException, JsonMappingException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        LOGGER.info("Store Before Post: " + store.getName());
        store = mapper.readValue(request, Store.class);
        LOGGER.info("Store After Post: " + store.getName());
        return "store";
    }

}

我已经在 BeanConfig 配置了存储 bean class:

@Configuration
public class BeanConfig {

    @Bean(name = "store")
    @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Store store() {
        Store store = new Store();
        store.setName("Test Store Name");
        return store;
    }
}

这是我的托管 bean:

@ManagedBean
@SessionScoped
public class StoreView extends SpringBeanAutowiringSupport {

    private static final Logger LOGGER = LoggerFactory.getLogger(Store.class);

    //@ManagedProperty("#{store}")
    @Autowired
    private Store store;

    public void test() {
        LOGGER.info("TEST " + store.getName());
    }

    //getters and setters
}

最后是我的 xhtml:

<h:panelGrid columns="3">
    <p:outputLabel for="j_store" value="#{messages['storeview.name']}" />
    <p:inputText id="j_store" value="#{storeView.store.name}" />
    <p:message for="j_store" />
    <h:panelGroup />
    <p:commandButton value="#{messages['storeview.test']}" action="#{storeView.test}" update="@form" ajax="false" />                                                                        
</h:panelGrid>

当我第一次使用邮递员发布示例数据时,记录器输出:

10:35:57,433 INFO  [com.store.test.controllers.StoreController] (default task-2) Store Before Post: Test Store Name
10:35:57,488 INFO  [com.store.test.controllers.StoreController] (default task-2) Store After Post: posted store name

如果我继续调用控制器,我会一直得到 "posted store name",所以它保留了值。

但是当我转到 store.xhtml 并点击测试按钮提交表单时,它仍然具有在 bean 配置文件 ("Test Store Name") 中设置的值,并且从那时起它保留我在 inputText 中提交的值。

我怀疑它与Spring和Faces上下文有关,我不知道我想做的事情是否可行。如果是,请指出我应该更改什么才能使其工作,否则,请为我提供替代解决方案。

提前致谢。

您正在混合使用 @Autowired@ManagedBean 注释。 @Autowired 由 Spring 管理,而 @ManagedBean 由 JSF 管理。 这意味着您可能有 2 个 Store 实例,由控制器修改的实例与托管 bean 使用的实例不同。

您应该在托管 bean 中将您的商店属性注释为 @ManagedProperty("#{store}"),并定义 getter 和 setter。 要让它工作,您还必须在 faces-config.xml

中定义 spring 表达式语言解析器
<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

由于jsf session和mvc session不同,你也必须在Store对象的定义中使用singleton scope。

@Scope(value = "singleton"........