[Spring]스프링 빈을 컨테이너에 등록하는 방법

2025. 1. 22. 09:01·개발/Spring

스프링 IoC 컨테이너는 설정 메타데이터를 읽어들이고 빈을 생성하여 관리하는 방식으로 작동한다고 했다.

그러면 실제로 어떻게 스프링 빈을 등록하는지 알아보자.

 

1.어노테이션 

자바 객체를 만들때는 클래스를 작성한다. 해당 클래스명에 어노테이션을 사용하면 편리하게 스프링 빈으로 등록 할 수 있다.

1. 어노테이션으로 스프링 빈을 등록하는 방법과 핵심 어노테이션:

  • @Component: 가장 기본이 되는 어노테이션으로,클래스명에 붙어 해당 클래스를 스프링 빈으로 등록하도록 지시
    • 일반적으로 특별한 역할이 없는 클래스에 사용
  • 스테레오타입(Stereotype) 어노테이션: @Component를 상속받아 만들어진 어노테이션.  마찬가지로 스프링 빈으로 등록되며, 특정 계층이나 역할등의 의미를 부여하기 위해 사용되는어노테이션이다. 
    • @Service: 서비스(Service) 계층의 빈. 비즈니스 로직을 담당하는 클래스에 사용
    • @Repository: 데이터 접근(Data Access) 계층(DAO 등)의 빈. 데이터베이스 연동과 관련된 클래스에 사용
    • @Controller: MVC의 컨트롤러 역할을 하는 빈. 사용자 요청을 처리하고 뷰를 반환하는 클래스에 사용
    • @RestController: RESTful API를 위한 컨트롤러 빈. @Controller와 @ResponseBody의 조합으로, 메서드의 반환 값이 HTTP 응답 본문(Response Body)으로 변환된다.

2. 어노테이션으로 등록된 빈을 찾는 방법(@ ComponentScan):

@ComponentScan은 스프링 프레임워크에서 어노테이션 기반의 빈(Bean) 자동 감지 및 등록을 위해 사용하는 핵심 기능이다. 쉽게 말해, 특정 패키지 내에서 @Component 및 관련 스테레오타입 어노테이션(@Service, @Repository, @Controller 등)이 붙은 클래스들을 자동으로 스캔하여 스프링 빈으로 등록해주는 역할을 한다.

@ComponentScan의 역할 및 동작 방식:

  1. 스캔 대상 지정: @ComponentScan은 어떤 패키지를 스캔하여 빈을 찾을지 지정.
    • basePackages 속성을 사용하여 스캔할 패키지 목록을 문자열 배열로 지정가능.
    • basePackageClasses 속성을 사용하여 특정 클래스가 속한 패키지를 스캔 대상으로 지정가능. (타입 안정성 제공)
    • basePackages나 basePackageClasses를 지정하지 않으면, @ComponentScan이 선언된 클래스의 패키지가 기본 스캔 대상.
  2. 어노테이션 스캔: @ComponentScan은 지정된 패키지 및 그 하위 패키지를 재귀적으로 탐색하면서 @Component, @Service, @Repository, @Controller, @Configuration 등 @Component를 상속받은 어노테이션이 붙은 클래스들을 찾는다.
  3. 빈 등록: 스캔된 클래스들을 스프링 빈으로 자동 등록.
    • 빈의 이름은 기본적으로 클래스 이름의 첫 글자를 소문자로 변환한 것이 사용. (e.g., MyService 클래스 -> myService 빈)
    • @Component("customBeanName")과 같이 어노테이션의 value 속성을 사용하여 빈 이름을 직접 지정가능.
    • 스프링 빈 이름은 빈을 식별하는 고유한 식별자(Identifier) 역할

javaCofig가 아닌 XML 설정으로 찾을때는 <context:component-scan> 태그를 이용한다.

3. 예제

1. ProductRepository, ProductService 클래스에 각각 @Repository, @Service 어노테이션을 붙여 빈으로 등록
2.
AppConfig 클래스에서 @ComponentScan을 사용하여 "com.example" 패키지 이하를 스캔
3. ApplicationContext를 통해 빈 이름을 확인하여 빈 등록 여부를 검증

프로젝트 구조:

com.example
├── config
│   └── AppConfig.java
├── service
│   └── ProductService.java
└── repository
    └── ProductRepository.java

1. @Repository를 사용한 빈 등록 (ProductRepository.java)

Java
 
package com.example.repository;

import org.springframework.stereotype.Repository;

@Repository("productRepository") // 빈 이름: "productRepository"
public class ProductRepository {

    public void saveProduct(String productName) {
        System.out.println(productName + " 상품을 저장했습니다.");
    }
}
  • @Repository : ProductRepository 클래스를 "productRepository"라는 이름으로 빈 등록

2. @Service를 사용한 빈 등록 (ProductService.java)

Java
 
package com.example.service;

import org.springframework.stereotype.Service;

@Service // 빈 이름: "productService" (클래스 이름 기준 자동 생성)
public class ProductService {

    public void addProduct(String productName) {
        System.out.println(productName + " 상품을 추가합니다.");
    }
}
  • @Service : ProductService 클래스를 "productService"라는 이름으로 빈 등록 (클래스 이름 기준)

3. @ComponentScan 설정 (AppConfig.java)

Java
 
package com.example.config;

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

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}
  • @Configuration : AppConfig 클래스를 Java Config 설정 파일로 지정
  • @ComponentScan : "com.example" 패키지 및 그 하위 패키지에서 @Component 관련 어노테이션 스캔

4. Main 클래스 (실행 및 빈 확인)

Java
 
package com.example;

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

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

        // 등록된 빈 이름 확인
        String[] beanNames = context.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            System.out.println("등록된 빈: " + beanName);
        }
    }
}
  • AnnotationConfigApplicationContext : AppConfig 설정 로드
  • getBeanDefinitionNames() : 컨테이너에 등록된 모든 빈 이름 조회

실행 결과:

등록된 빈: org.springframework.context.annotation.internalConfigurationAnnotationProcessor
등록된 빈: org.springframework.context.annotation.internalAutowiredAnnotationProcessor
등록된 빈: org.springframework.context.annotation.internalCommonAnnotationProcessor
등록된 빈: org.springframework.context.event.internalEventListenerProcessor
등록된 빈: org.springframework.context.event.internalEventListenerFactory
등록된 빈: appConfig
등록된 빈: productRepository
등록된 빈: productService
  • @Repository로 등록한 productRepository 빈과 @Service로 등록한 productService 빈이 정상적으로 등록된 것을 확인 가능
  • appConfig 빈도 @Configuration 어노테이션에 의해 자동으로 등록된것을 볼 수 있다.
  • org.springframework.context.annotation...로 시작하는 빈들은 스프링 내부에서 사용하는 빈

 

 

 

2. XML

 

클래스를 이용하지 않고 xml과 JavaConfig를 이용하는 방법이 있다.

클래스를 이용하는 방법은 간편하지만 분산되어있다는 단점이 있으며,

내가 직접 만든 객체가 아닌 외부 라이브러리를 이용할때에는 사용 할 수 없다는 단점이 있다.

XML에서 <bean> 태그를 사용한 스프링빈 등록 방법:

1. 기본 빈 등록:

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

    <bean id="빈이름" class="패키지.포함.클래스이름">
        </bean>

</beans>
  • id 속성 (필수): 빈의 고유한 이름(식별자)을 지정
  • class 속성 (필수): 빈으로 등록할 클래스의 FQCN(Fully Qualified Class Name)을 지정

2. 팩토리 메서드를 통한 빈 등록:

  • factory-method 속성: 정적 팩토리 메서드를 호출하여 빈을 생성할 때 사용.
XML
 
<bean id="myService" class="com.example.MyServiceFactory" factory-method="createInstance" />
Java
 
// com.example.MyServiceFactory.java
public class MyServiceFactory {
    public static MyService createInstance() {
        return new MyServiceImpl();
    }
}
  • 설명: com.example.MyServiceFactory 클래스의 정적 팩토리 메서드 createInstance()를 호출하여 반환된 객체를 myService라는 이름으로 빈 등록.
  • factory-bean, factory-method 속성: 인스턴스 팩토리 메서드를 호출하여 빈을 생성할 때 사용.
XML
 
<bean id="myServiceFactory" class="com.example.MyServiceFactory" />
<bean id="myService" factory-bean="myServiceFactory" factory-method="createInstance" />
Java
 
// com.example.MyServiceFactory.java
public class MyServiceFactory {
    public MyService createInstance() {
        return new MyServiceImpl();
    }
}
  • 설명: myServiceFactory 빈의 createInstance() 팩토리 메서드를 호출하여 반환된 객체를 myService라는 이름으로 빈 등록.

 

 

3. Java Config

Java Config를 이용하여 스프링 빈에 등록하면 xml에 비해 빈 생성 매소드 내부에 자바 객체를 사용하기 수월하다는 장점이 있다. 과거 레거시 코드에는 xml을 많이 사용했지만 Java Config를 점점 많이 사용하는 추세이다.

1. Java Config 스프링빈 등록 방법:

  • @Configuration: 클래스 레벨에 붙여 설정 클래스임을 선언.
  • @Bean: 메서드에 붙여 빈 생성 팩토리 메서드임을 선언.
  • 메서드 이름: 빈의 이름(id) 으로 사용됨 . @Bean(name = "...")으로 직접 이름 지정 가능.
  • 반환 타입: 빈의 타입(class) 을 나타냄.
  • 메서드 본문: 빈 객체 생성 및 초기화 로직을 작성.
  • 의존성 주입: 필요한 경우, @Bean 메서드의 파라미터로 의존성 주입.
  • AnnotationConfigApplicationContext: Java Config 설정 클래스를 로드하여 빈을 생성하고 관리하는 컨테이너.

2. 예시:

Java
 
@Configuration
@ComponentScan("com.example")
public class AppConfig {

    @Bean(name = "myRepo") // 빈 이름 변경
    public MyRepository myRepository() {
        return new MyRepositoryImpl();
    }
}

설명:

  • AppConfig 클래스는 @Configuration 어노테이션으로 설정 클래스로 선언됨
  • myRepository 메서드는 @Bean 어노테이션으로 MyRepository 타입의 빈을 생성하며, 빈의 이름을 myRepo로 명시적으로 설정함.
저작자표시 비영리 변경금지 (새창열림)

'개발 > Spring' 카테고리의 다른 글

[Spring] 스프링 빈 주입 방법  (0) 2025.03.13
[Spring] 의존성 주입 어노테이션  (0) 2025.03.13
[Spring] 스프링 빈의 라이프 사이클  (0) 2025.01.23
[Spring] 스프링 컨테이너의 종류와 주요 메소드  (0) 2025.01.23
[Spring] IoC / DI 란 무엇일까?  (0) 2025.01.22
'개발/Spring' 카테고리의 다른 글
  • [Spring] 의존성 주입 어노테이션
  • [Spring] 스프링 빈의 라이프 사이클
  • [Spring] 스프링 컨테이너의 종류와 주요 메소드
  • [Spring] IoC / DI 란 무엇일까?
함수형 인간
함수형 인간
잘 까먹는 개발자의 두뇌 확장 장치
  • 함수형 인간
    개발 기록 노트
    함수형 인간
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 글 목록 (84)
      • 기타 (1)
      • 개발 (82)
        • Java (6)
        • Javascript (1)
        • Spring (20)
        • jQuery (0)
        • Git (0)
        • servlet (11)
        • JSP (6)
        • HTML (0)
        • CSS (10)
        • SQL (9)
        • JSTL (3)
        • Mybatis (4)
        • Design Patterns (0)
        • HTTP (2)
        • Devtools (0)
        • IntelliJ (5)
        • JDBC (1)
        • Lombok (3)
        • Logging (1)
      • 책 리뷰 (0)
  • hELLO· Designed By정상우.v4.10.3
함수형 인간
[Spring]스프링 빈을 컨테이너에 등록하는 방법
상단으로

티스토리툴바