Spring Bean 을 등록하는 3가지 방법

Spring Bean

Spring Bean은 Spring Framework에서 관리하는 객체를 의미합니다.

Spring IoC (Inversion of Control) 컨테이너는 애플리케이션에서 객체의 생명 주기와 의존성 주입(Dependency Injection)을 관리합니다. Spring에서 관리하는 객체는 모두 Bean이라고 부르며, 이는 Spring 컨테이너가 생성하고 관리하는 객체입니다.

Spring Bean을 등록하는 방법

고전적인 방법 - Spring Bean XML 설정

먼저 등록하고 싶은 Bean 파일을 만들어야 합니다.

MyService 객체가 MyRepository 의존성을 갖고 있다고 가정하겠습니다.
public class MyService {

  private final MyRepository myRepository;

  public MyService(MyRepository myRepository) {
    this.myRepository = myRepository;
  }

}

public class MyRepository {}

 

src → main → java → resources 폴더에 application.xml 이름으로 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="MyService" class="com.example.my.MyService">
      <property name="myRepository" ref="myRepository"/>
    </bean>
  
    <bean id="MyRepository" class="com.example.my.MyRepository"/>
</beans>

 

이렇게 bean 이라는 Tag를 이용해서 Bean을 등록하였습니다.

빈을 등록할 때 id 는 카멜케이스, ref 속성은 첫 글자를 소문자로 시작해야 합니다.

 

이러한 과정은 MyService 와 MyRepository를 빈으로 만들라는 것입니다.

또한 MyService 가 MyRepository 빈을 주입받을 수 있도록 설정을 추가했습니다.

 

이렇게 등록한 빈은 ApplicationContext 를 통해 확인하고 사용하실 수 있습니다.

 

DemoApplication.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import java.util.Arrays;
 
public class DemoApplication {
 
    public static void main(String[] args) {
 
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        System.out.println(Arrays.toString(beanDefinitionNames)); // [MyService, MyRepository]
 
 	MyService myService = (MyService) context.getBean("MyService");
        System.out.println(myService.myRepository != null); // true
    }
}

 

ApplicationContext 에서 MyService 빈을 꺼내 MyRepository 가 null 이 아닌지 확인해 봄으로써 의존성 주입이 제대로 됐는지 알 수 있습니다. 

 

component scan 을 이용한 Bean 등록

기존 application.xml 파일에 다음과 같이 컴포넌트 스캔에 대한 정보를 입력합니다.

<context:component-scan> 엘리먼트를 등록하여 컴포넌트 스캔을 통한 Bean 등록을 할 것이라고 알려줍니다.

그리고 base-package 속성에 컴포넌트 스캔을 진행할 대상 루트패키지를 작성합니다. 그러면 해당 패키지를 포함한 모든 하위 패키지의 Bean 설정을 스캔하여 등록하게 됩니다.

 

application.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
 
    <context:component-scan base-package="com.example.my"/>
 
</beans>

 

빈을 등록하긴 하지만 모든 클래스를 빈으로 등록하는 것은 아니며 @Component 어노테이션이 붙은 클래스를 빈으로 등록합니다. @Component 말고도 @Service, @Repository 같은 경우도 이에 해당합니다.

 

MyService.java

import org.springframework.stereotype.Service;
 
@Service
public class MyService {
 
    public final MyRepository myRepository;
 
    public void MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}

 

MyRepository.java

import org.springframework.stereotype.Repository;

@Repository
public class MyRepository {}

 

이렇게 MyService 와 MyRepository 클래스에 각각 @Service, @Repository 애노테이션을 붙여줍니다.

그러면 두 클래스가 빈으로 등록이 됩니다. 또한 생성자 주입으로 인하여 의존성 주입까지 완료했습니다.

 

이렇게 빈 등록과 의존성 주입을 위한 설정이 모두 완료가 되면 main()을 실행해 보면 이전과 동일한 결과가 나옵니다.

 

JAVA 설정 파일의 사용

앞에서 작성한 application.xml 과 같은 XML 파일이 아닌 순수 JAVA 로도 설정파일을 만들 수 있습니다.

src → main → java → com.example.my 폴더 안에 ApplicationConfig.java 파일을 만들어 줍니다.

 

ApplicationConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class ApplicationConfig {
 
    @Bean
    public MyRepository myRepository() {
        return new MyRepository();
    }
 
    @Bean
    public MyService myService() {
        MyService myService = new MyService();
        myService.setMyRepository(myRepository());
        return myService;
    }
}

 

DemoApplication.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
import java.util.Arrays;
 
public class DemoApplication {
 
    public static void main(String[] args) {
 
//        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        System.out.println(Arrays.toString(beanDefinitionNames));
 
        MyService myService = (MyService) context.getBean("MyService");
        System.out.println(myService.myRepository != null);
    }
}

 

추가적으로 java 설정 파일에서 직접 setter 를 호출하지 않고 생성자 주입을 만들어서 의존성을 주입하는 것도 가능합니다

 

ApplicationConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class ApplicationConfig {
 
    @Bean
    public MyRepository myRepository() {
        return new MyRepository();
    }
 
    @Bean
    public MyService myService() {
        return new MyService;
    }
}

 

MyService.java

import org.springframework.stereotype.Service;
 
public class MyService {
 
    public final MyRepository myRepository;
 
    public void MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
}

'Spring' 카테고리의 다른 글

Spring - @Value  (1) 2024.12.20
스프링 빈(Bean) 이란?  (1) 2024.12.16
Spring - 경로 변수  (0) 2024.12.12
[Spring MVC] - QueryString  (0) 2024.12.12