'Streoptype'에 해당되는 글 1건

들어가며


스프링은 @ComponentScan은 서버 실행시 @Component 어노테이션 및 streotype(@Controller, @Servicie, @Repository)이 지정된 클래스들을 찾아 Bean으로 등록해주는 역할을 합니다. 우리는 streotype 이외에 @Component, @Configuration 어노테이션을 이용하여 사용자가 생성한 클래스들을 지정하여 등록하여 주는데 이번 포스팅에선 두 어노테이션의 차이를 알아보도록 하겠습니다.



Streotype 흝어보기


Spring은 Component-Scan을 통해서 Bean을 등록하여 줍니다. Streotype에 API를 확인해 보면 다들 @Component 어노테이션이 선언 되어 있는 것을 확인할 수 있습니다.


 @Controller 

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";

}

@Repository

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {

/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";

}

@Service

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";

}



Configuration의 API를 확인해보면 Streotype과 마찬가지로 @Component가 선언되어 있는 것을 확인할 수 있습니다.

 

@Configuration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

/**
* Explicitly specify the name of the Spring bean definition associated with the
* {@code @Configuration} class. If left unspecified (the common case), a bean
* name will be automatically generated.
* <p>The custom name applies only if the {@code @Configuration} class is picked
* up via component scanning or supplied directly to an
* {@link AnnotationConfigApplicationContext}. If the {@code @Configuration} class
* is registered as a traditional XML bean definition, the name/id of the bean
* element will take precedence.
* @return the explicit component name, if any (or empty String otherwise)
* @see AnnotationBeanNameGenerator
*/
@AliasFor(annotation = Component.class)
String value() default "";

/**
* Specify whether {@code @Bean} methods should get proxied in order to enforce
* bean lifecycle behavior, e.g. to return shared singleton bean instances even
* in case of direct {@code @Bean} method calls in user code. This feature
* requires method interception, implemented through a runtime-generated CGLIB
* subclass which comes with limitations such as the configuration class and
* its methods not being allowed to declare {@code final}.
* <p>The default is {@code true}, allowing for 'inter-bean references' via direct
* method calls within the configuration class as well as for external calls to
* this configuration's {@code @Bean} methods, e.g. from another configuration class.
* If this is not needed since each of this particular configuration's {@code @Bean}
* methods is self-contained and designed as a plain factory method for container use,
* switch this flag to {@code false} in order to avoid CGLIB subclass processing.
* <p>Turning off bean method interception effectively processes {@code @Bean}
* methods individually like when declared on non-{@code @Configuration} classes,
* a.k.a. "@Bean Lite Mode" (see {@link Bean @Bean's javadoc}). It is therefore
* behaviorally equivalent to removing the {@code @Configuration} stereotype.
* @since 5.2
*/
boolean proxyBeanMethods() default true;

}


 즉 @Component, @Configuration, @Controller, @RestController, @Service, @Repository 어노테이션은 서버 실행시 Component-Scan을 통해 Bean이 등록되는 것을 API 문서를 통해 확인할 수 있었습니다. 


@Component, @Configuration 차이


@Configuration

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors().disable()
.csrf().disable()
.formLogin().disable() // 로그인 폼 해제
.headers().frameOptions().disable();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}


@Component


@Component
public class FileUtils {

public int createDirectory(String path){

File dir = new File(path);
int cnt = 0;

if (!dir.exists()) {
try{
dir.mkdir();
cnt++;
} catch(Exception e){
e.getStackTrace();
}
}

return cnt;
}

public int createFile(MultipartFile file, String path){

int cnt = 0;
if (!file.isEmpty()){
try {
file.transferTo(new File(path + file.getOriginalFilename()));
cnt++;
} catch (IOException e) {
e.printStackTrace();
}
}
return cnt;
}
}



@Component 와 @Configuration은 큰 차이는 없습니다. 

위에서 보앗듯이, @Configuration의 내부를 살펴보면 @Component가 정의되어 있습니다. 따라서 @Component와 @Bean을 비교하는 것이 맞습니다.


우선적으로, 개발자가 직접 작성한 클래스에 대하여 @Component는 위와 같이 bean으로 등록 할 수 있습니다. 반대로 라이브러리 혹은 내장 클래스등 개발자가 직접 제어가 불가능한 클래스의 경우 @Configuration + @Bean 어노테이션을 이용하여 bean으로 등록하여 사용하면 됩니다.



정리

 

 @Component

 - 개발자가 직접 작성한 클래스를 bean 등록하고자 할 경우 사용


 @Configuration + @Bean

 - 외부라이브러 또는 내장 클래스를 bean으로 등록하고자 할 경우 사용. 

 - 1개 이상의 @Bean을 제공하는 클래스의 경우 반드시 @Configuraton을 명시


블로그 이미지

사용자 yhmane

댓글을 달아 주세요