我通过定义一个托管属性将一个托管bean注入另一个托管bean遇到了一些麻烦。我正在谷歌搜索和stackoverflow 3天,但没有结果…
我正在使用Eclipse 4.2进行开发并将其部署到集成的Tomcat 7中
那么,谁能告诉我,为什么我的财产为空?
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中设置了可扫描@Autowired注释的bean。(是的,我在applicationContext中没有使用bean的情况下进行了尝试,但是ManagedProperty也不会设置。)
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。
我愿意提出改善我的概念的建议!
你的JSF后备bean(MainBean和UserBean)应该由JSF或Spring来管理,但不能同时由两者来管理。
如果你的bean是由JSF管理的:
@...Scoped
@ManagedProperty
@Autowired@ManagedProperty
@ManagedProperty("#{userDao}") private UserDao userDao;
如果你的bean是由Spring管理的:
@ManagedBean
@Autowired
在这两种情况下,你都需要在以下位置配置Spring-JSF桥faces-context.xml:
faces-context.xml
<application> <el-resolver> org.springframework.web.jsf.el.SpringBeanFacesELResolver </el-resolver> </application>