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 :-)