@ComponentScan

초코칩·2024년 4월 18일
0

spring

목록 보기
6/10
post-thumbnail

@ComponentScan이란?

@ComponentScan은 Spring Framework에서 사용되는 어노테이션으로, 스프링이 어떤 패키지를 스캔하여 Application Context에 Bean을 등록할지를 지정하는 데 사용된다. 이 어노테이션을 사용하면 자동으로 Bean을 등록할 패키지를 지정할 수 있다.

일반적으로, 스프링 애플리케이션에서는 여러 클래스가 서로 의존하는 경우가 많다. 이때, 이러한 클래스들을 Application Context에 Bean으로 등록해야 한다. @ComponentScan 어노테이션을 사용하면 프레임워크가 특정 패키지 또는 패키지의 하위 패키지를 스캔하여 @Component 및 그와 유사한 어노테이션이 붙은 클래스를 찾아서 자동으로 빈으로 등록한다.

@ComponentScan을 써야 하는 이유

먼저 @ComponentScan 어노테이션을 활용해야 하는 이유에 대해 알아보자.

명시적인 빈 등록

아래 College.java 파일이 존재한다. College 클래스를 Bean으로 등록하기 위해서는 xml에 Bean으로 등록해야 한다.

package ComponentAnnotation;

public class College {
	public void test()
	{
		System.out.println("Test College Method");
	}
}

xml에 <bean> 태그를 이용해서 다음과 같이 작성할 수 있다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
		https://www.springframework.org/schema/context/spring-context.xsd">

	<bean id="collegeBean" class="ComponentAnnotation.College"></bean>
</beans>

Component Scan이 필요한 이유

위 방식의 문제점은 Bean으로 등록해야 하기 위해서 xml에 매번 작성하는 것은 번거롭다는 것이다.

이를 해결하기 위해 나온 개념이 Component Scan이다. Component Scan을 사용하면 개발자가 일일이 각각의 Bean을 등록할 필요가 없다. 대신 스프링이 특정 패키지 또는 패키지의 하위 패키지를 스캔하여 Bean으로 등록할 클래스를 찾아 자동으로 Bean을 생성하고 관리한다.

Component Scan 적용

기존 College 클래스를 Component Scan의 대상이 되게 하기 위해 @Component 어노테이션을 활용할 수 있다.

package ComponentAnnotation;

import org.springframework.stereotype.Component;

@Component("collegeBean")
public class College {
	public void test()
	{
		System.out.println("Test College Method");
	}
}

기존의 xml 파일에 아래 xml 태그를 추가한다.

<context:component-scan base-package="ComponentAnnotation"/>

<context:component-scan> 태그는 Spring Framework에서 XML 구성 파일에서 Component Scan을 설정하는 데 사용된다. base-package 속성은 스캔할 기본 패키지를 지정한다.

따라서 <context:component-scan base-package="ComponentAnnotation"/>은 "ComponentAnnotation" 패키지와 그 하위 패키지를 스캔하여 스프링 컨텍스트에 있는 컴포넌트 어노테이션(@Component, @Service, @Repository, @Controller 등)이 붙은 클래스를 찾아서 자동으로 Bean으로 등록하도록 설정한다는 것을 의미한다.

@Service, @Repository, @Controller 내부에 메타 어노테이션으로 @Component가 정의돼 있다.

하지만 위 방식은 여전히 xml에 의존적이다. 차라리 모든 설정 정보를 java로 구성하면 java, xml 파일을 찾아보지 않고, 일괄적으로 관리할 수 있을 것이다.

그래서 자바에서 설정 클래스를 만들고 이 클래스를 설정 클래스로 만들기 위해@Configuration 어노테이션을 활용할 수 있다.

@ComponentScan 어노테이션

기존 College 클래스를 그대로 두되, xml이 아닌 CollegeConfig 클래스를 생성하여 설정정보를 정의한다.

package ComponentAnnotation;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "ComponentAnnotation")
public class CollegeConfig {
}
  • @Configuration: 이 어노테이션은 해당 클래스를 Spring의 구성 클래스로 지정한다. 이는 XML 구성 파일 대신 Java 기반의 설정을 사용할 때 사용된다.

  • @ComponentScan: 이 어노테이션은 지정된 패키지 또는 패키지들에서 컴포넌트를 검색하도록 Spring에 지시한다. 여기서 basePackages 속성은 컴포넌트를 찾을 패키지를 지정한다. 위의 코드에서는 "ComponentAnnotation" 패키지 내에서 컴포넌트를 찾도록 지정되어 있다. 이는 해당 패키지와 그 하위 패키지들에서 @Component 어노테이션이 붙은 클래스들을 찾아 Spring 컨테이너가 관리하도록 한다.

CollegeConfig라는 Configuration 클래스를 사용하여 컴포넌트 스캔을 활성화하고, 해당 패키지 내에서 관리할 컴포넌트들을 등록한다.

기존 xml을 활용하던 Main에서 ClassPathXmlApplicationContext 대신에 AnnotationConfigApplicationContext를 활용하여 CollegeConfig 클래스를 Application Context 생성의 구성 파일로 등록해야 한다.

package ComponentAnnotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
	public static void main(String[] args)
	{
		ApplicationContext context
			= new AnnotationConfigApplicationContext(CollegeConfig.class);

		College college	= context.getBean("collegeBean", College.class);
            
		college.test();
	}
}

이로써 자동적으로 Component Scan을 활용할 수 있다.

Spring Boot의 Component Scan

그럼 Spring Boot 프로젝트에서는 Component Scan을 어떻게 진행될까?

그 답은 @SpringBootApplication 어노테이션에 답이 있다.

Spring Boot 프로젝트를 생성하면, 다음과 같이 기본적으로 생성된다.

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

@SpringBootApplication

@SpringBootApplication의 내부를 들여다보면 여러 어노테이션들이 정의되어 있다.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
//...
}

@SpringBootApplication 어노테이션을 사용하여 세 가지 기능을 활성화할 수 있다.

  • @EnableAutoConfiguration: Spring Boot의 자동 구성 메커니즘을 활성화한다. 제공된 의존성을 바탕으로 사용자가 필요로 할 Bean을 추측해 구성한 뒤 Application Context를 활성화한다. spring.factories 내부에 여러 Configuration 들이 있고, 조건에 따라 Bean을 등록한다.

  • @ComponentScan: 애플리케이션이 위치한 패키지에서 @Component 스캔을 활성한다.
  • @SpringBootConfiguration: 컨텍스트에 추가적인 빈(bean)을 등록하거나 추가 구성 클래스를 가져오도록 합니다. Spring의 표준 @Configuration 대안으로, 통합 테스트에서의 구성 감지를 도와준다.

즉, @SpringBootApplication 어노테이션은 Spring Boot 애플리케이션에서 자동 구성, 컴포넌트 스캔, 추가적인 구성을 활성화하는 데 사용된다.

Ref

profile
초코칩처럼 달콤한 코드를 짜자

0개의 댓글