스프링에서, 클래스 단위에 @Configuration을 생략하고 메소드에 @Bean 어노테이션을 붙여주어도 작동할까?
@EnableWebSecurity
//@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
@Override
@Autowired
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(encode().encode("password"))
.roles("USER");
}
@Bean
public PasswordEncoder encode() {
return new BCryptPasswordEncoder();
}
}
Spring Security를 설정해주는 SecurityConfig 클래스를 작성하고, @Configuration 어노테이션을 생략한 채로, 포스트맨을 통해 서버에 request를 날려주었다. 결과는, 매우 잘 작동한다. 그렇다면 @Configuration 어노테이션은 필수일까?
다음, 스택오버플로우에 매우 적절한 답변을 찾을 수 있었다.
https://stackoverflow.com/questions/51709087/is-configuration-mandatory_
public class DemoServiceUsage {
DemoService demoService;
public DemoServiceUsage(DemoService demoService) {
this.demoService = demoService;
}
}
public class NotAnnotatedConfiguration {
@Bean
public DemoService demoService() {
DemoService demoService = new DemoService();
System.out.println("demoService " + demoService.hashCode());
return demoService;
}
@Bean
public DemoServiceUsage demoServiceUsage1() {
return new DemoServiceUsage(demoService());
}
@Bean
public DemoServiceUsage demoServiceUsage2() {
return new DemoServiceUsage(demoService());
}
}
@Configuration
@Import({
NotAnnotatedConfiguration.class
})
public class ApplicationConfig {
}
@ContextConfiguration(classes = ApplicationConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class NotAnnotatedConfigurationTest {
@Autowired
DemoServiceUsage demoServiceUsage1;
@Autowired
DemoServiceUsage demoServiceUsage2;
@Test
public void load() {
assertNotNull(this.demoServiceUsage1);
assertNotNull(this.demoServiceUsage2);
}
}
'Spring will load the config class and also create instances but will not treat the instances as beans'
스프링 빈은 기본적으로 싱글톤 패턴으로 사용되기 때문에, @Configuration 어노테이션을 명시해주지 않는다면, 위의 예제 소스코드 결과를 실행해보면 알 수 있는데 각각의 demoService가 서로 다른 해쉬코드를 가지고 있는 것을 알 수 있다. 이는 @Configuration 어노테이션이 내부적으로 @Component 어노테이션을 사용하고 있고, 이는 @ComponentScan의 대상이 되기 때문에 반드시 @Bean 메소드를 사용하는 클래스에는 @Configuration 어노테이션을 명시해주는 것이 좋다.