Reputation: 70
I've created a spring application using spring-security with java based configuration. I've also included a jar file (created by me) in my project. The problem I am facing is:- i have to write @ComponentScan(basePackages = {"com.mypackage"}) in both the classes (SpringConfig.java and SecurityConfig.java) which leads to initialization of beans twice. Removing either of @componentscan leads to error:- Error creating bean with name 'securityConfig'.
Below are my java classes.
SpringConfig.java
package com.mypackage.config;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"com.mypackage"})
public class SpringConfig extends WebMvcConfigurerAdapter {
private static final Logger logger = LoggerFactory.getLogger(SpringConfig.class);
@PostConstruct
public void init(){
logger.debug("Spring Config initialized");
}
}
SecurityConfig.java
package com.mypackage.config;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = {"com.mypackage"})
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
//This Configuration class is in my jar file.
// with package starting with same name com.mypackage
@Autowired
com.mypackage.frameworks.config.Configuration config;
@PostConstruct
public void init(){
logger.debug("Security config initiaziled");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
try {
auth.inMemoryAuthentication()
.withUser("admin").password("admin").roles("USER");
} catch (Exception e) {
e.printStackTrace();
}
}
}
MyController.java
package com.mypackage.controller;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
@Controller
public class MyController {
private static final Logger logger = LoggerFactory.getLogger(MyController.class);
@PostConstruct
public void init(){
logger.debug("-------Controller created-------");
}
}
Upvotes: 0
Views: 4369
Reputation: 589
You have configured bean definitions into multiple @Configuration classes. My suggestion is - Aggregating @Configuration classes with @Import into single place. Now you can able to apply @ComponentScan(basePackages = {"com.mypackage"}) in one place and context also loads bean only one time.
The @Import annotation provides just this kind of support, and it is the direct equivalent of the element found in Spring beans XML files. Please refer this link - https://docs.spring.io/spring-javaconfig/docs/1.0.0.M4/reference/html/ch04s03.html
Upvotes: 1
Reputation: 506
Beans will be configured and created twice because both application context scans the same package "com.mypackage". One solution is to separate SpringConfig beans package from SecurityConfig beans package. be as more specific as you can in @ComponentScan package value
Upvotes: 0