【问题标题】:Autowired injected variable is null [duplicate]自动装配的注入变量为空 [重复]
【发布时间】:2015-07-19 22:29:02
【问题描述】:

我有一个名为UniqueEmailValidatorFacesValidator 类来确定输入的电子邮件是否唯一。

我需要userService 变量,所以我通过spring 注入它。

这里是UniqueEmailValidator.java

@FacesValidator("com.obs.bean.uniqueEmailValidator")
@Component
public class UniqueEmailValidator implements Validator {

    @Autowired
    private UserService userService;

    public void validate(FacesContext fc, UIComponent uic, Object value) throws ValidatorException {
        if (value == null) {
            return;
        }
        String email = (String) value;
        System.out.println("userService before use: " + userService); // null
        boolean exists = userService.emailExists(email);
        if (exists) {
            throw new ValidatorException(new FacesMessage(
                    FacesMessage.SEVERITY_ERROR, "Email already in use", null));
        }
    }
}

这里是UserServiceImple.java

@Service
public class UserServiceImpl implements UserService<User, Integer>, Serializable {

@Autowired
@Qualifier("userDao")
private UserDao userDao;

@Transactional()
public boolean emailExists(String value) {
    Query query = userDao.getSession().createQuery("from User where email=?");
    query.setString(0, value);
    if (query.uniqueResult() != null) {
        return true;
    }
    return false;
  }
}

但是userServicenull,(我得到nullPointerException

我在applicationContext.xml也有这行:

<!-- Activates scanning of @Autowired -->
<context:annotation-config/>

<!-- Activates scanning of @Repository and @Service -->
<context:component-scan base-package="..."/>

【问题讨论】:

  • 看起来 JSF 正在管理 UniqueEmailValidator 的实例而不是 Spring,因此您无法注入任何对象。
  • @LuiggiMendoza 那么有什么解决办法吗?
  • 我不会在这种情况下使用验证器,就这么简单。
  • 对于这种特殊情况,我会在数据库中设置一个唯一键,尝试插入并处理未满足唯一键约束的异常。如果您仍然希望/需要向用户显示一条好消息以进行验证,那么我建议您在 action 中处理此验证。这不是正确的方法,但您可以为这种情况做些什么。另外,我会向 JSF 人员提交一张票,以添加对在验证器和转换器上注入 CDI/Spring/Guice bean 的支持。
  • 顺便说一下,mkyong 有这个:mkyong.com/jsf2/spring-autowired-into-jsf-custom-validator

标签: spring jsf autowired


【解决方案1】:

当您使用标签启用验证器时

<f:validator validatorId="validatorId"/>

然后验证器实例由 JSF 实现创建(通过获取类并调用 newInstance()),因此它不会被识别为 Spring bean 并且自动装配不起作用。要将验证器实例作为 Spring bean 获取,您必须使用 binding 属性:

<f:validator binding="#{validatorBeanName}"/>

在这种情况下,注释@FacesValidator 不是必需的。

【讨论】:

    【解决方案2】:

    您可以尝试为您的自动装配服务使用参数化声明

    @Autowired
    private UserService<User, Integer> userService;
    

    或者尝试使用@Qualifier 并为您的服务命名

    @Service("myService")
    public class UserServiceImpl ...
    

    ...

    @Autowired
    @Qualifier("myService")
    private UserService<User, Integer> userService;
    

    【讨论】:

      猜你喜欢
      • 2011-12-26
      • 2015-12-02
      • 2019-04-06
      • 2015-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-13
      相关资源
      最近更新 更多