반응형
스프링에서 사용하는 Bean에 대한 개념을 알아보자
1. Bean이란?
- "빈(Bean)"은 스프링 컨테이너에 의해 관리되는 객체이다. 빈은 일반적으로 애플리케이션에서 사용되는 객체를 나타내며, 스프링의 IoC 컨테이너에서 생성, 구성, 관리된다.
@Component를 사용하여 Bean을 등록하는 코드 예시
- 아래의 코드를 보자 MyBean이라는 class 상단에는 @Component라는 어노테이션이 표시되어 있다.
- 이는 MyBean이라는 클래스가 스프링의 빈(Bean)으로 등록되어야 함을 나타낸다. 즉, MyBean 클래스의 인스턴스(객체)는 스프링 컨테이너에 의해서 생성되고 관리되게 된다.
@Component
public class MyBean {
private String name;
public MyBean() {
this.name = "Default Name";
}
}
위의 예시코드에서 등록해준 스프링 Bean을 사용하는 코드 예시
- 아래의 MyBeanUser 클래스는 내부에 MyBean을 의존성으로 가지고 있다. 이 의존성은 생성자 주입방식을 통해서 주입받게 된다(생성자가 1개만 있을때는 @Autowired를 생략해도 된다.).
- MyBeanUser 클래스는 printName() 메서드를 통해서 주입된 MyBean을 사용해서 myBean.getName()으로 이름을 출력한다.
public class MyBeanUser {
private MyBean myBean;
// 생성자가 1개일때는 @Autowired 생략해도 된다.
public MyBeanUser(MyBean myBean) {
this.myBean = myBean;
}
public void printName() {
System.out.println("Name: " + myBean.getName());
}
}
2. @Component란?
- 위의 예시를 보면 @Component 어노테이션이 사용되었다. 이게 뭔지 알아보자
@Component
- @Component는 스프링 프레임워크에서 사용되는 어노테이션 중 하나로, 해당 클래스를 스프링의 빈으로 등록하는 데 사용된다. 이것은 일반적인 스프링 빈으로 사용될 수 있는 클래스의 상단에 적어서 사용한다.
- @Component 어노테이션은 @Controller, @Service, @Repository 등 다른 특수한 용도를 가진 어노테이션들의 메타 어노테이션이기도 하다. 따라서, @Component 어노테이션을 사용하여 클래스를 빈으로 등록하면, 해당 클래스는 일반적인 컴포넌트로 사용되거나, 특수한 용도의 컴포넌트로 사용될 수 있다.
한번 더 @Component의 사용 예제코드를 보자
- 아래의 코드에서 MyComponent 클래스 위에 @Component 어노테이션을 추가했다. 이렇게 하면 MyComponent 클래스가 스프링의 빈으로 등록된다.
- 스프링 컨테이너는 @ComponentScan 어노테이션을 통해 스캔할 패키지를 지정 후 @Component 어노테이션이 달린 클래스를 스캔후 인스턴스를 생성하여 관리한다. 이렇게 등록된 빈은 다른 빈에서 의존성 주입을 통해 사용할 수 있다.
- 또한, @Component 어노테이션은 value 속성을 통해 빈의 이름을 지정할 수 있다. 기본적으로는 클래스 이름의 첫 글자를 소문자로 변환한 이름이 빈의 이름으로 사용된다.
- 예를 들어, MyComponent 클래스의 빈 이름은 "myComponent"가 된다. 하지만, @Component("customName")과 같이 명시적으로 이름을 지정할 수도 있다.
@Component // 선택
// @Component("customName")
public class MyComponent {
// ...
}
3. @ComponentScan이란?
@ComponentScan에 대해서 알아보자
@ComponentScan
- @ComponentScan은 스프링에서 사용되는 어노테이션으로, 지정된 패키지에서 컴포넌트를 스캔하여 자동으로 Bean으로 등록하는 기능을 수행한다. @ComponentScan 어노테이션은 주로 스프링 컨텍스트가 @Component를 찾을 수 있도록 지시하는 데 사용된다.
- 스프링 부트에서는 메인 실행 클래스에 가보면 적혀있는 @SpringBootApplication 어노테이션에 @ComponentScan이 내장되어 있다.
- @SpringBootApplication을 사용하여 애플리케이션을 구성하면, @ComponentScan이 자동으로 실행되어 애플리케이션의 클래스 경로에서 컴포넌트를 찾고 스프링 빈으로 등록한다.
- @ComponentScan 어노테이션은 스프링의 강력한 기능 중 하나로, 자동으로 빈을 등록하여 개발자가 직접 빈을 구성하고 등록하는 번거로움을 덜어준다. 이를 통해 애플리케이션의 개발 생산성을 향상시킬 수 있다.
@ComponentScan 예시 코드
package hello.aop;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AopApplication {
public static void main(String[] args) {
SpringApplication.run(AopApplication.class, args);
}
}
- @SpringBootApplication 내부에 아래와 같이 @ComponentScan이 있다.
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
@ComponentScan 설명
- @ComponentScan 어노테이션의 속성을 보자 첫번째는 excludeFilters 속성을 사용하여 스캔에서 제외할 빈을 설정하는 부분이다. excludeFilters는 Filter 배열로 구성되어 있으며, 스캔에서 제외할 빈을 정의하는 데 사용된다.
- 각 Filter는 type과 classes 속성을 가지고 있다. 여기서 FilterType.CUSTOM은 커스텀 필터를 사용하겠다는 것을 의미한다. 즉, TypeExcludeFilter와 AutoConfigurationExcludeFilter라는 두 개의 커스텀 필터 클래스를 지정한 것이다.
- TypeExcludeFilter는 타입을 기준으로 스캔에서 제외할 빈을 필터링하는 역할을 한다. 일반적으로 특정 타입의 빈을 스캔에서 제외하려는 경우 사용된다. AutoConfigurationExcludeFilter는 자동 설정을 기준으로 스캔에서 제외할 빈을 필터링하는 역할을 한다.
- 스프링 부트는 자동 설정을 통해 애플리케이션을 구성하는데, 이 설정을 제외하려는 경우 사용된다.
4. @Component로 등록시킨 객체는 프록시 객체인가? 원본 객체인가?
@ComponentScan을 사용하여 등록된 빈은 일반적으로 프록시 객체가 아니라 원본 클래스의 인스턴스이다.
스프링은 필요한 경우에만 프록시 객체를 생성하여 AOP 등의 기능을 제공한다.
프록시 객체 or 원본 객체?
- @ComponentScan을 사용하여 컴포넌트를 스캔하고 등록할 때, 모든 컴포넌트가 프록시 객체가 아닌 원본 인스턴스로 등록된다. @Component 어노테이션이 붙은 클래스는 스프링 컨테이너에서 일반적인 빈으로 등록되며, 프록시 객체로 래핑되지 않는다.
- 기본적으로 스프링은 @Component 어노테이션이 붙은 클래스를 인스턴스화하여 빈으로 등록한다. 이 인스턴스는 프록시가 아니며, 원본 클래스의 인스턴스이다. 스프링 컨테이너는 이러한 빈 인스턴스를 생성하고 의존성 주입 등을 수행하여 관리한다.
- 다만, AOP와 같은 특정한 상황에서는 스프링이 프록시 객체를 생성하여 빈을 래핑할 수 있다. AOP를 사용하는 경우에는 대상 빈에 대한 프록시 객체가 생성되어 부가적인 기능을 제공하고, 필요에 따라 메서드 호출을 가로챌 수 있다. 하지만 @ComponentScan으로 스캔된 모든 빈이 자동으로 프록시 객체로 생성되는 것은 아니다.
2023.08.09 - [Spring 기초/spring 설정] - [스프링, 스프링부트] Spring - Xml vs @Configuration
반응형
'Spring 기초 > Spring 기초 지식' 카테고리의 다른 글
스프링의 핵심: Singleton 패턴 알아보기 (0) | 2023.08.07 |
---|---|
스프링 프레임워크의 핵심: 제어의 역전(IoC) (0) | 2023.08.07 |
[스프링, 스프링부트] Spring - 의존성 주입(DI - Dependency Injection) (0) | 2023.08.07 |
[스프링, 스프링부트] Spring Container (스프링 컨테이너) (0) | 2023.08.07 |
[스프링, 스프링부트] Spring Framework (0) | 2023.07.20 |