3

I have problems with two services that i autowired in a validator class. The services works ok because in my controller are autowired. I've an applicationContext.xml file and MyApp-servlet.xml file. My base package is es.unican.meteo and i have problems with the package es.unican.meteo.validator. The package es.unican.meteo.controller and es.unican.meteo.service can autowire the services properly.

applicationContext.xml

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

....
some beans
...
</beans>

Myapp-servlet.xml

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

    <!-- Enabling Spring beans auto-discovery -->
    <context:component-scan base-package="es.unican.meteo" />

    <!-- Enabling Spring MVC configuration through annotations -->
    <mvc:annotation-driven />

Class ResetPasswordValidator:

package es.unican.meteo.validator;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import es.unican.meteo.model.User;
import es.unican.meteo.service.MessageService;
import es.unican.meteo.service.UserService;

public class ResetPasswordValidation  implements Validator{

    @Autowired
    private UserService userService;

    @Autowired
    private MessageService messageService;

    public boolean supports(Class<?> clazz) {
        return User.class.equals(clazz);
    }

    public void validate(Object target, Errors errors) {
        User user = (User)target; 
        if(userService.getUserByEmail(user.getEmail())==null){
            errors.rejectValue("email", messageService.getMessage("app.error.nonexistentemail"));
        }
    }
}

I can see the controllers, services and autowired elements in the Spring elements. It seems like spring is not detecting the autowired properties in the package validator. Any ideas?

Edit: Log of the ResetPasswordValidation (Autowire fields)

12:48:50,697 DEBUG main support.DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'resetPasswordValidation'
12:48:50,697 DEBUG main support.DefaultListableBeanFactory:430 - Creating instance of bean 'resetPasswordValidation'
12:48:50,701 DEBUG main annotation.InjectionMetadata:60 - Found injected element on class [es.unican.meteo.validator.ResetPasswordValidation]: AutowiredFieldElement for private es.unican.meteo.service.UserService es.unican.meteo.validator.ResetPasswordValidation.userService
12:48:50,702 DEBUG main annotation.InjectionMetadata:60 - Found injected element on class [es.unican.meteo.validator.ResetPasswordValidation]: AutowiredFieldElement for private es.unican.meteo.service.MessageService es.unican.meteo.validator.ResetPasswordValidation.messageService
12:48:50,702 DEBUG main support.DefaultListableBeanFactory:504 - Eagerly caching bean 'resetPasswordValidation' to allow for resolving potential circular references
12:48:50,707 DEBUG main annotation.InjectionMetadata:85 - Processing injected method of bean 'resetPasswordValidation': AutowiredFieldElement for private es.unican.meteo.service.UserService es.unican.meteo.validator.ResetPasswordValidation.userService
mannuk
  • 1,259
  • 5
  • 21
  • 43

1 Answers1

3

Make sure you annotate the class so Spring picks it up as a bean. Autowiring can only occur on beans/classes managed by the DI container.

Adding @Component will cause the class to be picked up by Spring's component scanning, causing ResetPasswordValidation to become a bean. At this point, it should be eligible to have fields autowired.

@Component
public class ResetPasswordValidation  implements Validator
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • Your point is very interesting @Kevin. Now the eclipse project detects that i have autowired elements in the validation class but it is not injecting the services. The properties are still null, maybe do i need more things? – mannuk Jul 11 '13 at 10:31
  • Yes @Kevin, the services in the controller classes works fine. I've added the piece of log that corresponds to the ResetPasswordValidation – mannuk Jul 11 '13 at 10:56
  • I found my mistake @kevin. I was creating an instance of ResetPasswordValidation with new(...); Now i have an autowired property of the validator in my controller. Thank you very much for your answers because the Component was necessary! – mannuk Jul 11 '13 at 11:07
  • @mannuk Glad I could help. I made the mistake with new before too. – Kevin Bowersox Jul 11 '13 at 11:52
  • and i will take a look to your blog :) – mannuk Jul 12 '13 at 12:23
  • @mannuk Please ignore its lack of being updated recently. I hope to get back on track, but I am so busy at the moment. – Kevin Bowersox Jul 12 '13 at 12:26
  • Besides of autowire the validator in my controller I've added this: @InitBinder protected void initBinder(WebDataBinder binder) { binder.setValidator(commentCommand) } Now it's working! – Iván López Jul 15 '14 at 17:55