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

时间:2018-08-29 07:50:20

标签: spring ejb

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

假设我们具有以下域类(为了简化可读性,我将其简化):

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

    //constructors, getters and setters...
}

@JsonProperty的原因是因为我从另一个将Json张贴到以下Controller的应用程序中获取了此值:

@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:

@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

如果我继续调用控制器,我将继续获取“已发布的商店名称”,因此它将保留该值。

但是,当我转到store.xhtml并单击“测试”按钮提交表单时,它仍具有在Bean配置文件中设置的值(“测试存储名称”),从那时起,它保持该值我在inputText中提交的内容。

我怀疑这与Spring和Faces上下文有关,我不知道我想做的事是否可行。如果是这样,请指出我应该进行哪些更改以使其起作用,否则,请向我提供替代解决方案。

谢谢。

1 个答案:

答案 0 :(得分:1)

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

您应该在托管bean中将您的商店属性注释为@ManagedProperty("#{store}"),并定义getter和setter。 为了使其工作,您还必须在faces-config.xml中定义spring表达式语言解析器

<application>
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

由于jsf会话不同于mvc会话,因此还必须在Store对象的定义中使用单例作用域。

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