Spring 托管 bean 中的 @ManagedProperty 为空 [英] @ManagedProperty in a Spring managed bean is null

查看:26
本文介绍了Spring 托管 bean 中的 @ManagedProperty 为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过定义托管属性将一个托管bean 注入另一个托管bean 时遇到了一些麻烦.我现在用谷歌搜索和计算器溢出了 3 天,但没有结果......

I've some trouble with injecting one managedbean in another by defining a managedproperty. I'm googling and stackoverflowing now for 3 days, but with no result...

我正在使用 Eclipse 4.2 进行开发并部署到集成的 Tomcat 7

I'm developing with eclipse 4.2 and deploying to an integrated Tomcat 7

那么,谁能告诉我,为什么我的财产是空的?

So, can anybody tell me, why my property is null?

pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.version>3.0.5.RELEASE</spring.version>
        <java.version>1.6</java.version>
    </properties>    
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

web.xml

    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" 
    http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

我已经在 applicationContext 中设置了 bean 来扫描 @Autowired 注释.(是的,我在 applicationContext 中没有 bean 的情况下尝试过,但是 ManagedProperty 也不会被设置.)

I have set the beans in applicationContext for scanning @Autowired annotation. (Yes, i tried it without beans in applicationContext, but ManagedProperty will not be set, too.)

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:annotation-config />

<context:component-scan base-package="myPackage" />

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

<bean class="myPackage.dao.UserDao" id="userDao" />
<bean class="myPackage.dao.WorldDao" id="worldDao" />
<bean class="myPackage.dao.BuildingTypeDao" id="buildingTypeDao" />
<bean class="myPackage.dao.BuffTypeDao" id="buffTypeDao" />
<bean class="myPackage.dao.ClanDao" id="clanDao" />

<bean class="myPackage.bean.MainBean" id="mainBean" />
<bean class="myPackage.bean.UserBean" id="userBean" />
<bean class="myPackage.bean.AdminBean" id="adminBean" />

MainBean

package myPackage.bean;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import myPackage.model.MainModel;

@ManagedBean
@SessionScoped
public class MainBean implements Serializable {

private static final long serialVersionUID = 1L;

private static final Logger logger = LoggerFactory.getLogger(MainBean.class);

private MainModel model;

/**
 * @return the model
 */
public MainModel getModel() {
    if (model == null) {
        model = new MainModel();
    }
    return model;
}

/**
 * @param model the model to set
 */
public void setModel(MainModel model) {
    this.model = model;
    }
}

UserBean

package myPackage.bean;

import java.io.Serializable;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import myPackage.dao.UserDao;
import myPackage.entity.User;

@ManagedBean
@RequestScoped
public class UserBean implements Serializable {

private static final long serialVersionUID = 1L;

private static final Logger logger = LoggerFactory.getLogger(UserBean.class);

@ManagedProperty(value="#{mainBean}")
private MainBean mainBean;

@Autowired
private UserDao userDao;

/**
 * @return the mainBean
 */
public MainBean getMainBean() {
    return mainBean;
}

/**
 * @param mainBean the mainBean to set
 */
public void setMainBean(MainBean mainBean) {
    this.mainBean = mainBean;
}

public String doLogin() {
    User user = userDao.getUserByUsernameAndPassword(getMainBean().getModel().getUser().getUsername(), getMainBean().getModel().getUser().getPassword());
    if (user != null) {
        getMainBean().getModel().setUser(user);
        logger.info("User '"+getMainBean().getModel().getUser().getUsername()+"' logged in");
        getMainBean().getModel().setSelectedTab(0);
    } else {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Login failed", "Username and/or password wrong!"));
        logger.warn("User '"+getMainBean().getModel().getUser().getUsername()+"' login failed");
    }
    return null;
}

UserDao

package myPackage.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import myPackage.entity.User;

@Repository
public class UserDao {

@PersistenceContext
private EntityManager entityManager;

@Transactional
public void save(User user) {
    if (user.getId() == null) {
        entityManager.persist(user);    
    } else {
        entityManager.merge(user);
    }
}

@SuppressWarnings("unchecked")
public List<User> list() {
    return entityManager.createQuery("select u from User u")
            .getResultList();
}

public User getUserByUsername(String username) {
    try {
        Query q = entityManager.createQuery("select u from User u where u.username = :username");
        q.setParameter("username", username);
        User u = (User) q.getSingleResult();
        return u;
    } catch (Exception e) {
        return null;
    }
}

public User getUserByUsernameAndPassword(String username, String password) {
    try {
        Query q = entityManager.createQuery("select u from User u where u.username = :username and u.password = :password");
        q.setParameter("username", username);
        q.setParameter("password", password);
        User u = (User) q.getSingleResult();
        return u;
    } catch (Exception e) {
        return null;
    }
}

@Transactional
public User getUserById(Long id) {
    return entityManager.find(User.class, id);
}

@Transactional
public void delete(User user) {
    entityManager.remove(user);
}

public void deleteById(Long id) {
    delete(getUserById(id));
}

}

现在例外...

Caused by: java.lang.NullPointerException
    at myPackage.bean.UserBean.doLogin(UserBean.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)

第 47 行:

    User user = userDao.getUserByUsernameAndPassword(getMainBean().getModel().getUser().getUsername(), getMainBean().getModel().getUser().getPassword());

调试显示 getMainBean() 返回 null.

Debugging shows that getMainBean() returns null.

我愿意接受改进我的概念的建议!

I'm open for suggests to improve my concept!

推荐答案

您的 JSF 支持 bean(MainBeanUserBean)应该由 JSF 或 Spring 管理,但不是他们两个.

Your JSF backing beans (MainBean and UserBean) should be managed either by JSF or by Spring, but not by both of them.

如果您的 bean 由 JSF 管理:

If your beans are managed by JSF:

  • 您使用 @ManagedBean@...Scoped
  • 注释它们
  • 您不需要在 applicationContext.xml
  • 中声明它们
  • 您使用 @ManagedProperty 而不是 @Autowired,即使您需要注入 Spring 管理的 bean(不要忘记 setter,@ManagedProperty 需要它):

  • You annotate them with @ManagedBean and @...Scoped
  • You don't need to declare them in applicationContext.xml
  • You use @ManagedProperty instead of @Autowired, even if you need to inject beans managed by Spring (don't forget setters, @ManagedProperty requires it):

@ManagedProperty("#{userDao}")
private UserDao userDao;

如果您的 bean 由 Spring 管理:

If your beans are managed by Spring:

  • 您在 applicationContext.xml 中使用适当的范围声明它们(不支持视图范围)
  • 你不需要 @ManagedBean@...Scoped
  • 您使用 @Autowired 而不是 @ManagedProperty 并且您不能以这种方式注入由 JSF 管理的 bean
  • You declare them in applicationContext.xml with appropriate scopes (view scope is not supported)
  • You don't need @ManagedBean and @...Scoped
  • You use @Autowired instead of @ManagedProperty and you cannot inject beans managed by JSF this way

在这两种情况下,您都需要在 faces-context.xml 中配置 Spring-JSF 桥:

In both cases you need to configure Spring-JSF bridge in faces-context.xml:

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

这篇关于Spring 托管 bean 中的 @ManagedProperty 为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆