Bean과 Component 차이

Jeongkuk Seo
sjk5766
Published in
5 min readFeb 20, 2023

미니 프로젝트를 통해 스프링 시큐리티를 사용할 때 Bean Component 다룰 일이 있었다. 이 둘의 차이를 모르기 때문에 간략하게 정리하고자 한다.

선언 위치의 차이

Configuration + Bean과 Component 어노테이션이 사용되면 모두 스프링의 IoC 컨테이너에 객체로 관리되며 어플리케이션 전역적으로 의존성 주입에 활용될 수 있다.

Bean과 Component 어노테이션의 첫 번째 차이는 선언 위치다. Component는 class level에 선언되고 Bean은 메소드 레벨에 선언된다.

가령 패스워드 암호화를 위해 Bcrypt를 사용하는 모듈을 Component로 제공한다고 하면 아래와 같이 class level에 component를 선언할 수 있다.

@Component
public class PasswordEncoder {
public String encode(String seed) {
return new BCryptPasswordEncoder().encode(seed);
}

public boolean matches(String seed, String password) {
return new BCryptPasswordEncoder().matches(seed, password);
}
}

만약 위 코드에서 Component 위치에 Bean을 사용한다면 IDE가 오류를 표시한다. 보면 Target이 METHOD만 지정하는 것을 확인할 수 있다.

아래는 위에서 표기되는 ElementType의 내부인데 Class에 사용되려면 TYPE 으로 선언되어야 함을 알 수 있다.

public enum ElementType {
/** Class, interface (including annotation interface), enum, or record
* declaration */
TYPE,

/** Field declaration (includes enum constants) */
FIELD,

/** Method declaration */
METHOD,

아래 코드는 스프링 시큐리티를 사용한다면 많이 볼 수 있는 코드인데 메소드레벨에 @Bean을 선언해서 IoC 컨테이너의 빈으로 등록할 수 있다.

@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}

사용법의 차이

Bean외부 라이브러리가 제공하는 객체를 사용할 때 활용하고 Component는 내부에서 직접 접근 가능한 클래스를 사용하면 된다. 위 예시에서 활용했던 코드를 다시보자.

@Component
public class PasswordEncoder {
public String encode(String seed) {
return new BCryptPasswordEncoder().encode(seed);
}

public boolean matches(String seed, String password) {
return new BCryptPasswordEncoder().matches(seed, password);
}
}

위 코드에서 Component 어노테이션을 쓸 수 있는 이유는 PasswordEncoder라는 class를 내가 직접 만들었기 때문이다. 만약 이 코드가 라이브러리에 있는 코드라면 나는 이 클래스에 Component를 추가할 수 없다. 따라서 라이브러에 있는 객체를 사용할 때는 Bean을 활용할 수 있다.

Bean과 Configuration

Bean을 사용시 Configuration 어노테이션을 꼭 사용해야 한다. 만약 아래와 같이 Bean만 선언했을 경우.

public class MyBean {
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}

이 Bean을 다른 곳에서 의존성 주입하는데 활용할 수 없다.

Configuration 어노테이션을 사용하면 정상적으로 IoC 컨테이너에 등록되어 의존성 주입을 할 수 있는데 사실 Configuration 내부에 Component 어노테이션이 있다.

--

--