Introduction

Spring is a great platform with very many different projects. I used the Spring Framework before, but now was the time to try Spring Boot with the annotation-based configuration instead of the XML-based conf in the earlier versions.

A great starting point for Spring Boot is the SPRING INITIALIZR project, which makes it really easy to bootstrap a base system for your development efforts.

I choose a configuration with Thymeleaf as template engine and imported everything into Intellj Idea. I created some new packages and also some controllers, but when I started the system the controllers where not registered in the request mapper. Every time I tried to access the webpage I received the 404 error page from /error.

So what was happening:

Application configuration class:

package me.kamwo.mcs.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class McsApplication {

    public static void main(String[] args) {
        SpringApplication.run(McsApplication.class, args);
    }
}

Some controller:

package me.kamwo.mcs.presentation.control;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * Created by kamwo on 15.02.15.
 */
@Controller
public class HomeController {

    @RequestMapping(value = "/")
    public String index(){
        System.out.println("Home Page");
        return "index";
    }
}

Everything looked normal :-) But why was it not working. Lets take a look at the @SpringBootApplication annotation:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 */
	Class<?>[] exclude() default {};

}

The point which stands out is the @ComponentScan annotation which scans the packages for Spring components. The @SpringBootApplication will execute the package scan for the package me.kamwo.mcs.application, but the controller is located in me.kamwo.mcs.presentation.control so it will not be scaned. The solution is to remove the @SpringBootApplication, replace it add the basePackage path:

Pre Spring Boot 1.3.x

package me.kamwo.mcs.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "me.kamwo")
@EnableAutoConfiguration
public class McsApplication {

    public static void main(String[] args) {
        SpringApplication.run(McsApplication.class, args);
    }
}

Spring Boot 1.3.x upwards

Since Spring Boot 1.3.x upwards the @SpringBootApplication accepts a new parameter called scanBasePackages, where you can pass the package names, you would like to be scanned:

package me.kamwo.mcs.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication(scanBasePackages={"me.kamwo"})
public class McsApplication {

    public static void main(String[] args) {
        SpringApplication.run(McsApplication.class, args);
    }
}

Hope this post helps someone :-)