How to use tomcat with spring without web.xml?

Viewed 2536

I have a JAX-RS application deployed on Tomcat 7. I am deploying the application on Tomcat without any web.xml file.

I want to use spring for injecting some of the dependencies in my project. I am not using any XML file to configure beans, instead I have created a class and annotated it with @Configuration annotation, which contains all the bean definitions. Now, I am trying to use that bean by annotating a field in a separate class with @Autowired, but the field is null.

How should I make spring work with this setup ?

EDIT: I was able to initialize spring application context , by creating a web.xml in WEB-INF/ with the following contents.

<web-app>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

I checked the tomcat logs , and verified that the bean is created by spring. But the problem is when I try to use that bean, the field in the class is null.

4 Answers

You may want to use Spring Boot, which helps you develop a web application as easy as developing a stand-alone application that you can "just run".

According to official website of Spring Boot, you can create

  • Create stand-alone Spring applications
  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
  • Provide opinionated 'starter' POMs to simplify your Maven configuration
  • Automatically configure Spring whenever possible
  • Provide production-ready features such as metrics, health checks and externalized configuration
  • Absolutely no code generation and no requirement for XML configuration

You can learn it in just 1 hour I found this YouTube video very interesting watch Getting Started with Spring Boot.

If you want to use @Autowired the in a Class it first has to be a Bean. You can do this by annotating the Class with @Component or by using the @Bean Annotation in the Configuration.

@Bean
Yourclass yourclass(){
     return new YourClass();
}

Second you will have to add the @ComponentScan Annotation to your Configuration.

@ComponentScan("your.package")
@Configuration

Third you must instantiate an ApplicationContext. For example like this

JavaConfigApplicationContext context = new JavaConfigApplicationContext(YourConfig.class);

Because it is a Webapplication it probably would be best to have a look at WebApplicationInitializer, implement your own and initialize the Context there.

What you are missing is the way to initialize the Spring Dispatcher Servlet. You need to implement the interface WebApplicationInitializer and in this class, you pass all the Java configurations needed for your application.

You have to define AnnotationConfigWebApplicationContext where you can register your configuration class :

context.register(MyConfig.class);

or you can define the base packages containing all your config classes :

context.setConfigLocation("com.example.app.config");

Full example :

    public class MyWebAppInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext container) {
        AnnotationConfigWebApplicationContext context
          = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.example.app.config");

        container.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic dispatcher = container
          .addServlet("dispatcher", new DispatcherServlet(context));

        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

Last thing, if you use maven, don't forget to set the property failOnmissingwebxml to false in the pom.xml.

You can find more info here

Related