Is it possible to Autowire an object in a Validation class? I keep getting null for the object that is supposed to be Autowired...
-
Can you give an example? – skaffman Apr 29 '10 at 08:35
-
That is identical to how my project is laid out. what is even more confusing is that the @Autowire is working on the @Controller classes. the problem is that i am instantiating the AccessRequestValidator class inside of a Controller (vs setting it up in the a context xml file). I have annotated the Validator with @Component, but none of the @Autowire are working... – wuntee Apr 30 '10 at 04:07
2 Answers
Are your Validation class an enabled Spring bean ??? If not, you always will get null for your object autowired. Make sure you have enabled your Validation class.
And do not forget enable The Annotation config bean post-processor (see <context:annotation-config /> element)
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
</beans>
How to enable your Validation class as a managed Spring bean. Either
1° By using xml (As shown above)
<beans ...>
<bean class="AccessRequestValidator"/>
<context:annotation-config />
</beans>
2° By using annotation instead (Notice @Component just above class)
@Component
public class AccessRequestValidator implements Validator {
}
But to enable Spring annotated component scanning, you must enable a bean-post processor (notice <context:component-scan element)
<beans ...>
<context:annotation-config />
<context:component-scan base-package="<PUT_RIGHT_HERE_WHICH_ROOT_PACKAGE_SHOULD_SPRING_LOOK_FOR_ANY_ANNOTATED_BEAN>"/>
</beans>
Inside your Controller, just do it (Do not use new operator)
Choose one of the following strategies
public class MyController implements Controller {
/**
* You can use FIELD @Autowired
*/
@Autowired
private AccessRequestValidator accessRequestValidator;
/**
* You can use PROPERTY @Autowired
*/
private AccessRequestValidator accessRequestValidator;
private @Autowired void setAccessRequestValidator(AccessRequestValidator accessRequestValidator) {
this.accessRequestValidator = accessRequestValidator;
}
/**
* You can use CONSTRUCTOR @Autowired
*/
private AccessRequestValidator accessRequestValidator;
@Autowired
public MyController(AccessRequestValidator accessRequestValidator) {
this.accessRequestValidator = accessRequestValidator;
}
}
UPDATE
Your web app structure should looks like
<CONTEXT-NAME>/
WEB-INF/
web.xml
<SPRING-SERVLET-NAME>-servlet.xml
business-context.xml
classes/
/com
/wuntee
/taac
/validator
AccessRequestValidator.class
lib/
/**
* libraries needed by your project goes here
*/
Your web.xml should looks like (NOTICE contextConfigLocation context-param and ContextLoaderListener)
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<!--If your business-context.xml lives in the root of classpath-->
<!--replace by classpath:business-context.xml-->
<param-value>
/WEB-INF/business-context.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name><SPRING-SERVLET-NAME></servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name><SPRING-SERVLET-NAME></servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
Your <SPRING-SERVLET-NAME>-servlet.xml should looks like (Notice i am using Spring 2.5 - replace if you are using 3.0)
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!--ANY HANDLER MAPPING-->
<!--ANY VIEW RESOLVER-->
<context:component-scan base-package="com.wuntee.taac"/>
<context:annotation-config/>
</beans>

- 33,349
- 20
- 110
- 136
-
I think he's referring to validator classes that are *not* managed by Spring, in which case `annotation-config` won't make a difference. – skaffman Apr 29 '10 at 08:35
-
i am not sure what you mean by 'managed/not-managed by spring'... i have a class that implements Validator and is used in the Controller like: AccessRequestValidator validator = new AccessRequestValidator(); validator.validate(accessRequestBean, result); – wuntee Apr 29 '10 at 13:50
-
3@wuntee You really do not have a Spring managed bean. If you create some instance by using new operator, how can Spring manage your instance ? I will show you how to get your goal – Arthur Ronald Apr 29 '10 at 15:11
Trying to follow what you show above, I am still getting a null pointer:
context.xml:
<context:annotation-config />
<context:component-scan base-package="com.wuntee.taac"/>
AccessRequestValidator.java
package com.wuntee.taac.validator;
@Component
public class AccessRequestValidator implements Validator {
@Autowired
private UserAccessCache userAccessCache;
...
}
business-context.xml:
<bean id="userAccessCache" class="com.wuntee.taac.controller.UserAccessCache">
<property name="cadaDao" ref="cadaDao" />
<property name="adDao" ref="adDao" />
</bean>
Does the scanner recursively scan the tree?

- 12,170
- 26
- 77
- 106
-
Strange, I'm seeing the same thing in my project now. A @Component-annotated Validator with an @Autowired field, but it's never wired up and remains null. – Haakon Jul 16 '10 at 13:47
-
8Update: I found my mistake. In my controller, I had an @InitBinder method with this code: binder.setValidator(new FooValidator()); So while Spring managed *a* FooValidator, I set my controller to use a different, unmanaged one. I just changed it to an autowired FooValidator. – Haakon Jul 16 '10 at 13:55