HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤩
개발
/
Spring
Spring
/
🎧
Spring Framework 핵심개념(Core)
/
🪠
빈 등록(@Bean, @Components, @Configuration)과 컴포넌트 스캔
🪠

빈 등록(@Bean, @Components, @Configuration)과 컴포넌트 스캔

컴포넌트 스캔(Bean Scan)Stereotype 애노테이션@Components 와 @Bean의 차이@Configuration 과 @Components의 차이@ComponentScan @SpringBootApplication 을 이용한 ComponentScan@SpringBootApplication@EnableJpaRepositories@ContextConfiguration

컴포넌트 스캔(Bean Scan)

  • 컴포넌트 스캔은 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능임. 설정 클래스에 빈으로 직접 등록하지 않아도 원하는 클래스를 빈으로 등록할 수 있음

Stereotype 애노테이션

  • 스프링이 자동으로 등록될 빈을 찾는 방법? ⇒ Stereotype 애노테이션 이용
    • stereo type ?? 의미는 고정관념. 사실 이 용어는 UML에서 온 것임. 특정 요소를 상황이나 도메인에 맞게 분류해 주는 것임
    • https://incheol-jung.gitbook.io/docs/q-and-a/spring/stereo-type
notion image

@Components 와 @Bean의 차이

  • @Component는 클래스 상단에 적으며 그 default로 클래스 이름이 bean의 이름이 된다. 또한 spring에서 자동으로 찾고(@ComponentScan 사용) 관리해주는 bean이다.
  • @Bean은 @Configuration으로 선언된 클래스 내에 있는 메소드를 정의할 때 사용한다. 이 메소드가 반환하는 객체가 bean이 되며 default로 메소드 이름이 bean의 이름이 된다.
    • @Bean(”<원하는 bean의 이름>”) 형태로 bean의 이름을 정할 수 있음
    • //만약, Encoder까지 bean에서 관리하려고 하면 @Component public class Encoder{ private IEncoder iEncoder; // IEncoder를 구현하는 클래스가 하나만 있다면 Qualifier 필요 없음 // 그러나 여러개 있으면 Qualifier로 어떤 클래스 객체를 넣어줄 것인지 써줘야함 public Encoder(@Qualifier("base64Encoder") IEncoder iEncoder){ this.iEncoder = iEncoder; } public encode(String message){ this.iEncoder.encode(message); } } // Encoder를 2가지로(base64, url) 만들어서 쓰고 싶을 때 @Configuration // 1개 클래스에서 여러 개의 bean을 등록 시 class AppConfig{ // 위에서 Base64Encoder가 base64Encoder의 이름을 가지므로 // 이름을 다르게 설정해주어야함 @Bean("base64Encode") public Encoder encoder(Base64Encoder base64Encoder){ return new Encoder(base64Encoder); } @Bean("urlEncode") public Encoder encoder(UrlEncoder urlEncoder){ return new Encoder(urlEncoder); } }

@Configuration 과 @Components의 차이

우아한 테크코스 블로그. Springboot-autoconfiguration
  • @Configuration 어노테이션 안에는 proxyBeanMethods() 라는 값이 존재하는데 이 값의 default 는 true 임 ⇒ 이 때, Configuration의 Proxy가 생성되고, Proxy는 그 내부의 Bean이 한 번만 생성되도록 관리함
  • 즉, @Bean을 이용하여 bean 생성은 @Configuration 에서만 해야 함. 그래야 싱글톤으로 관리 됨
  • 만약 @Components 안에서 @Bean을 생성하면 싱글톤으로 생성되는 것이 아닌 중복적으로 생성되게 됨
  • Aggregating @Configuration classes with @Import
    • where one @Configuration class logically imports the bean definitions defined by another.
    • @Configuration public class DataSourceConfig { @Bean public DataSource dataSource() { return new DriverManagerDataSource(...); } } @Configuration @AnnotationDrivenConfig @Import(DataSourceConfig.class) // <-- AppConfig imports DataSourceConfig public class AppConfig extends ConfigurationSupport { @Autowired DataSourceConfig dataSourceConfig; @Bean public void TransferService transferService() { return new TransferServiceImpl(dataSourceConfig.dataSource()); } }
      위와 같이 하면 AppConfig만 생성해도 DatasourceConfig도 같이 생성된다고 함 → 근데 이건 SpringBoot에서는 자동적으로 되는 부분이라 안해도 될듯

@ComponentScan

  • @Componenet 혹은 4개의 다른 annotation을 붙이고 @ComponentScan이라는 어노테이션을 @Configuration 클래스에 붙이게 되면 아래와 같이 identifed 했다는 로그가 발생함
    • ComponentScan을 하게 되면 같은 패키지 내에서 컴포넌트들을 다 찾아줌. 이 부분 명시 가능함
      • basePackages 옵션으로 설정 가능 — 이건 package의 path를 명시해주기 때문에 오타가 나면 못 찾아 낼 수 있음
      • 그럴 때 basePackageClasses 를 이용해서 class import 해서도 명시 가능함. 명시한 클래스가 속한 패키지의 component를 다 찾아줌
      • excludeFilters — 원하지 않는 component 스캔에서 제외
      • @ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType. .., value = )})
1:22:33.971 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/geuno/Desktop/Programmers/SpringBoot/dev-kdt-maven/target/classes/org/prgms/OrderService.class] 11:22:33.972 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/geuno/Desktop/Programmers/SpringBoot/dev-kdt-maven/target/classes/org/prgms/VoucherService.class]

@SpringBootApplication 을 이용한 ComponentScan

notion image
  • 단순히 위와 같은 구조에서 OrderTester가 @SpringBootApplication 어노테이션을 갖고 있으면 order, voucher package안에 있는 Component들은 다 알아서 컴포넌트 스캔이 진행됨. 왜냐하면 OrderTester가 위치한 곳이 basePackage가 되어서 그 안에 있는 것들은 다 스캔이 진행되기 때문에

@SpringBootApplication

notion image
@SpringBootConfiguration
  • 단 하나의 SpringBootConfiguration만 있어야 하고, 이게 root configuration이 됨 ⇒ @SpringBootApplication 이 하나라는 것
  • 별도로 Configuration 필요하면 따로 만들어서 @Configuration 붙여주어서 관리하고.
  • Spring에서 ApplicationContext 만들어서 거기서 bean얻어오고 할 때와 달리, test 환경에서도 자동으로 configuration을 찾아준다는 점이 편리한 점임
  • @ComponentScan annotation 이 있어서 위의 componentScan이 자동적으로 일어남
  • @EnableAutoConfiguration : enable Spring Boot’s auto-configuration mechanism
 

@EnableJpaRepositories

  • JpaRepository interface를 구현하는 인터페이스들을 빈으로 등록해주는 역할을 담당하는 어노테이션임
  • 스프링부트에서는 해당 어노테이션이 자동설정되기 때문에 따로 명시해주지 않아도 알아서 잘 찾음
 

@ContextConfiguration

  • 해당 어노테이션으로 특정 configuration class만 지정하면 해당 Configuration 에서 지정된 Bean들만 ApplicationContext에 올라가게 됨