Issue
I've generated a Spring Boot web application using Spring Initializr, using embedded Tomcat + Thymeleaf template engine, and package as an executable JAR file.
Technologies used :
Spring Boot 1.4.2.RELEASE, Spring 4.3.4.RELEASE, Thymeleaf 2.1.5.RELEASE, Tomcat Embed 8.5.6, Maven 3, Java 8
I have this security class
com.tdk.config
/**
* @author nunito
* @version 1.0
* @since 4 mar. 2017
*/
@Configuration
@EnableWebSecurity
@PropertySource("classpath:/com/tdk/config/app-${APP-KEY}.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected String loginPage = "/tdk/login";
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.loginPage(getLoginPage() )
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/mockup/**").permitAll()
.antMatchers("/welcome/**").authenticated()
.and()
.logout()
.permitAll()
.logoutSuccessUrl("/index.html");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.passwordEncoder(new StandardPasswordEncoder())
.withUser("nunito").password("08c461ad70fce6c74e12745931085508ccb2090f2eae3707f6b62089c634ddd2636f380f40109dfb").roles("ADMIN").and()
.withUser("nunito").password("4cfbf05e4493d17125c547fdba494033d7aceee9310f253f3e96c4f928333d2436d669d63a84fe4f").roles("ADMIN");
}
public String getLoginPage() {
return loginPage;
}
public void setLoginPage(String loginPage) {
this.loginPage = loginPage;
}
Using this config file
@SpringBootApplication
@ComponentScan(basePackages = "com.tdk.config")
@EnableAutoConfiguration
public class TdkCloudApplication {
public static void main(String[] args) {
SpringApplication.run(TdkCloudApplication.class, args);
}
}
I have a 404 wherever I access in the URL
But this config everything is OK
@SpringBootApplication
@EnableAutoConfiguration
@Import({SecurityConfig.class})
public class TdkCloudApplication {
public static void main(String[] args) {
SpringApplication.run(TdkCloudApplication.class, args);
}
}
I would like to know the difference, because for me is two different ways to do exactly the same think
Solution
This is an explanation of @Import
and @ComponentScan
, this is not an answer to your question (because I don't know why it doesn't work with ComponentScan), more like a hint for it.
@Import
is used for importing other configurations, so if a class is annotated with @Configuration
and there are some beans defined there, they will be imported to the application context, e.g.
@Configuration
public class config{
@Bean
public ClassA a(){
return new ClassA();
}
}
@Import({config.Class}) // import Bean for ClassA
@ComponentScan
scans all classes annotated with @Component
, @Service
, @Repository
and have a one to one bean mapped to each class.
e.g.
@Component
public class ClassB {}
@ComponentScan // import Bean ClassB
After the version 4.2 of Spring, @ComponentScan
can also scan @Configuration
as a component. So in your case, the SecurityConfig should also be imported into the context as a component but not as a configuration.
The only thing I don't quite understand is how the @Import
triggers the execution of the code in the SecurityConfig, please give a comment if anyone knows about it.
Answered By - Simon