I am new to spring and am creating a spring web application.
The application I'm writing has a Class PreLoadService
. In this class is a method defined with @PostConstruct
that calls a DAO to load the data. The DAO instance is declared in the class with the @autowired
.
The Controller for the JSP then declares an instance of the PreLoadService
and calls the getter to retrieve the data that should have been loaded in the @PostConstruct
. The data is never loaded and an exception is also thrown on the @autowired
.
Since this did not work I tried a simple Hello World version to write a message and received the same issue. I will post this. In the WEB_INF folder I have a web.xml
and a spring3-servlet.xml
. In the SRC folder I have an applicationContext.xml
. I am running on Tomcat 7.
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Spring3MVC</display-name>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>root.webpath</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>spring3</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring3</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>/</url-pattern>
</servlet-mapping></web-app>
spring3-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:p="http://www.springframework.org/schema/p"
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.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!--will allow Spring to load all the components from package and all its child packages-->
<mvc:annotation-driven />
<context:component-scan
base-package="com.nikki.spring3.controller" />
<!-- will resolve the view and add prefix string /WEB-INF/jsp/ and suffix .jsp to the view in ModelAndView. -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
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:p="http://www.springframework.org/schema/p"
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.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<mvc:annotation-driven/>
<context:component-scan base-package="com.nikki.spring3">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<bean id="helloWorldService"
class="com.nikki.spring3.beansit.HelloWorldService">
<property name="message" value="Preloading Init Config and Data" />
HelloWorldService
public class HelloWorldService {
private String message;
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
System.out.println("Your Message : " + message);
return message;
}
@PostConstruct
public void init(){
System.out.println("Bean is going through init.");
}
@PreDestroy
public void destroy(){
System.out.println("Bean will destroy now.");
}
}
HelloWorldController
@Controller
public class HelloWorldController {
@Autowired
HelloWorldService helloWorldService;
/* RequestMapping annotation tells Spring that this Controller should
* process all requests beginning with /hello in the URL path.
* That includes /hello/* and /hello.html.
*/
@RequestMapping("/hello")
public ModelAndView helloWorld() {
String message =helloWorldService.getMessage();
//"Hello World, Spring 3.0!";
return new ModelAndView("hello", "message", message);
}
}
Error Message
Exception
SEVERE: StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0':
Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'helloWorldController':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.nikki.spring3.beansit.HelloWorldService com.nikki.spring3.controller.HelloWorldController.helloWorldService;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [com.nikki.spring3.beansit.HelloWorldService] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
I appreciate any help. Thanks.
If you have config files other than xxx-servlet.xml you need to let know spring that these files exists. To do that you have to use contextConfigLocation along with ContextLoadListener. Try to add the following lines in your web.xml. If the applicationContext.xml exists in WEB-INF folder of the project use the following.
<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>
I think you had your applicationContext.xml under src folder. In that case use as below
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>