[Spring] IoC 컨테이너와 스프링부트 자동 설정

Jiwoo Jung·2024년 9월 27일
0

GDGoC Spring 스터디

목록 보기
3/15

GDG on Campus Backend-Spring 스터디 WIL
Week 2 - IoC 컨테이너와 스프링부트 자동 설정

1. IoC Container

Spring IoC Container

  • 객체(Bean) 생성
  • 객체들의 의존성 구성 및 조립(configures and assembles)
  • 객체들의 전체 생명 주기 관리

기본 패키지

  • org.springframework.beans
  • org.springframework.context

컨테이너를 통한 제어의 역전(IaC)

스프링에서는 개발자가 아닌 IoC 컨테이너가 자바 객체(Beans) 생성과 생명주기 관리에 대한 제어권을 가진다.

How?
1. IoC 컨테이너는 XML, 자바 어노테이션, 또는 자바 코드로 작성된 configuration metadata를 읽어 어떤 객체를 생성하고, 구성하고, 조립해야 하는지에 대한 정보를 얻는다.
2. 그 후, IoC 컨테이너는 빈을 생성할 때 필요한 의존성을 주입한다.

geeksforgeeks.org


BeanFactoryApplicationContext

BeanFactoryApplicationContext는 IoC 컨테이너를 대표하는 두가지 인터페이스이다.
BeanFactory는 IoC 컨테이너의 가장 기본적인 형태이며, ApplicationContextBeanFactory의 기능을 확장한 버전이다.

1. BeanFactory

org.springframework.beans.factory.BeanFactory

  • 가장 기본적인 IoC 컨테이너
  • 스프링 컨테이너가 빈을 만드는 공장(Factory)처럼 동작하기 때문에 "BeanFactory"라는 이름이 붙었다.
  • 빈의 생성, 구성, 생명주기 관리와 같은 고급 설정 메커니즘을 제공하는 가장 단순한 컨테이너이다.
  • 어노테이션 기반 설정 미지원 (ApplicationContext는 지원)

2. ApplicationContext

org.springframework.context.ApplicationContext

  • BeanFactory하위 인터페이스(Sub-interface)

  • BeanFactory를 확장하며, 그 기능의 상위 집합(Superset)이다.
    즉, BeanFactory가 제공하는 모든 기능을 포함한다.

  • 더 많은 엔터프라이즈급 기능을 추가로 제공한다.

    • 스프링 AOP 기능과 쉬운 통합
    • 메시지 리소스 처리 (internationalization)
    • 이벤트 발행 (Event publication)
    • 웹 애플리케이션을 위한 WebApplicationContext와 같은 애플리케이션 계층별 컨텍스트 제공

이러한 추가 기능들 때문에 개발자들은 일반적으로 BeanFactory보다 ApplicationContext를 선호한다.

image.png

geeksforgeeks.org



2. Spring Bean

docs.spring.io

  • 스프링에서 애플리케이션의 중심을 이루며 Spring IoC 컨테이너에 의해 관리되는 객체

컨테이너에 빈(Bean) 설정하기

bealdung.com
geeksforgeeks.org

1. Java-Based Configuration

  • 수동 등록
  • 가장 최신, 권장되는 방법
  • Spring 3.0부터 사용 가능
  • Method에만 사용
  • 주로 외부 라이브러리나 개발자가 직접 수정하기 어려운 클래스를 빈으로 등록할 때 사용

@Bean
메서드에 붙이는 어노테이션
해당 메서드가 스프링 빈을 생성함을 나타낸다.
메서드 이름이 빈의 ID(이름)가 된다.

@Configuration
클래스에 붙이는 어노테이션
해당 클래스가 스프링 빈 설정 정보를 담고 있음을 나타낸다.

// Java Program to Illustrate Configuration in College Class

package BeanAnnotation;

// Importing required classes
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CollegeConfig {

	// Using Bean annotation to create
	// College class Bean
	@Bean

	// Here the method name is the
	// bean id/bean name
	public College collegeBean()
	{

		// Return the College object
		return new College();
	}
}

2. Annotation-Based Configuration

What is Annotation?

프로그램에 대한 데이터를 제공하는 메타데이터의 한 형태로, 프로그램에 대한 보충 정보를 제공하기 위해 사용된다. 어노테이션은 코드의 동작에 직접적인 영향을 주지 않으며, 컴파일된 프로그램의 동작을 변경하지 않는다.

  • 자동 등록
  • Spring 2.5부터 도입
  • Class에만 사용
  • 주로 개발자가 직접 작성한 클래스를 빈으로 등록할 때 사용

@Component
스프링이 사용자 정의 빈을 자동으로 탐지할 수 있게 해준다.

How to use

  1. XML 설정 파일에서 어노테이션 기반 설정 활성화
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
  
  // 어노테이션 기반 설정 활성화
  <context:annotation-config/>
  <context:component-scan base-package="com.baeldung.applicationcontext"/>

</beans>
  • annotation-config 태그는 annotation-based mapping을 활성화한다.
  • component-scan 태그는 스프링에게 어노테이션이 붙은 클래스에 대해 어디를 봐야할지 알려준다.
    .
  1. 자바 클래스에 어노테이션을 붙여 빈 설정
    (@Component, @Controller, @Service, @Repository, @Autowired 등)
@Component
public class UserService {
	// user service code
}

3. XML-Based Configuration

  • 전통적인 방식
  • XML 설정 파일에 직접 빈을 정의.
<bean id="Bean 고유 ID" class="Bean으로 등록할 클래스 경로">
</bean>

Example

class.java

public class Student {
 
    private int id;
    private String studentName;
 
    public void displayInfo()
    {
        System.out.println("Student Name is " + studentName
                           + " and Roll Number is " + id);
    }
}

beans.xml ( 프로젝트의 classpath에 있는 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
	https://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="studentAmiya" class="Student">

	</bean>

</beans>

Bean Definition

docs.spring.io

빈의 이름, 스코프 등과 같은 정의 정보는 BeanDefinition 객체에 담겨 관리된다.

속성설명
Class인스턴스화할 빈의 클래스
Name빈의 이름 또는 ID
Scope빈의 스코프(생명주기 범위)
Constructor arguments생성자 주입에 사용될 인자
PropertiesSetter 주입에 사용될 프로퍼티
Autowiring mode자동 의존성 주입 모드
Lazy initialization mode지연 초기화 여부
Initialization method초기화 콜백 메서드
Destruction method소멸 콜백 메서드

Bean Scope

baeldung.com
docs.spring.io
topcoder.com

What is Bean Scope?

  • 빈의 생명주기(lifecycle)
  • 빈이 얼마나 오래 존재하고, 몇 개의 인스턴스가 생성되며, 어떻게 공유되는지를 정의
  • 기본(Default) 스코프는 싱글톤(singleton)

스코프 설정 방법

1. XML에서 설정

<bean id="accountService" class="com.something.DefaultAccountService"/>

<!-- 아래는 동일한 코드 -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

2. @Scope 어노테이션 사용

  • @Component, @Bean 어노테이션과 함께 사용된다.
@Component
@Scope("prototype") 
public class ShoppingList {   
}
@Bean
@Scope("singleton")
public Person personSingleton() {
    return new Person();
}
  • String 대신 상수로 설정 가능
    ex) @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)

스프링 프레임워크가 지원하는 6가지 스코프

  • singleton
  • prototype
  • (웹 환경 전용)
    • request
    • session
    • application
    • websocket

Singleton Scope

  • Spring IoC 컨테이너가 해당 빈의 인스턴스를 단 하나만 생성한다.
  • 생성된 유일한 인스턴스는 캐시(cache)에 저장되며, 이후 해당 빈에 대한 모든 요청과 참조는 캐시된 객체를 반환한다.

Scope 기본값이 Singleton인 이유
서버환경에서 수많은 요청이 올때마다 객체를 생성하면 큰 오버헤드가 발생한다. 따라서 스프링은 싱글톤으로 bean을 생성한다.

싱글톤 패턴의 문제점

  • private 생성자로 인해 상속할 수 없다.
  • mock 객체로 대체하기 어려워 테스트가 어렵다.
  • 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장할 수 없다. 여러개의 jvm 분산 → 독립적으로 객체 생성
  • 전역 상태를 만들기 때문에 객체지향적이지 않다.
    싱글톤의 static method를 이용해 언제든지 싱글톤에 접근할 수 있어 전역 상태로 사용될 수 있다.

스프링의 Singleton Registry

  • Singleton pattern의 단점 보완
  • 스프링 컨테이너(ApplicationContext)가 직접 bean을 singleton으로 관리한다.
  • private 생성자가 필요없고 일반 자바 클래스처럼 설계 가능

Prototype Scope

컨테이너에 요청할 때마다 매번 새로운 인스턴스를 생성하여 반환

일반적으로 상태를 가지는(stateful) 빈에는 프로토타입 스코프를, 상태가 없는(stateless) 빈에는 싱글톤 스코프를 사용하는 것이 좋다.


3. 조건부 어노테이션(Conditional Annotations)

geeksforgeeks.org

  • 특정 조건에 따라 빈의 생성 및 구성을 제어할 수 있게 해주는 어노테이션들

@Conditional

  • spring 4.0부터 사용 가능
  • 사용자 정의 조건에 따라 빈의 등록 여부를 결정
  • 클래스/메소드 레벨에서 사용될 수 있다.
  • Condition 인터페이스를 구현한 클래스를 만들어 빈 생성 로직을 직접 정의할 수 있다.

@ConditionalProperty

  • 특정 property가 존재하거나, 특정 값을 가질 때만 bean을 생성한다.
@Configuration
public class MyConfiguration {

    @Bean
    @ConditionalOnProperty(name = "my.property.enabled", havingValue = "true")
    public MyBean myBean() {
        return new MyBean();
    }
}

@ConditionalOnClass

  • classpath에 특정 클래스가 존재할 때만 bean을 생성한다.
@Configuration
public class MyConfiguration {

    @Bean
    @ConditionalOnClass(name = "com.example.MyClass")
    public MyBean myBean() {
        return new MyBean();
    }
}

@ConditionalOnMissingBean

  • 특정 type이나 이름이 ApplicationContext에 이미 정의되어있지 않을 때만 생성한다.
@Configuration
public class MyConfiguration {

    @Bean
    @ConditionalOnMissingBean(MyBean.class)
    public MyBean myBean() {
        return new MyBean();
    }
}

@ConditionalOnBean

  • 특정 bean type이나 이름이 ApplicationContext에 이미 정의되어 있을 때만 생성한다.
@Configuration
public class MyConfiguration {

    @Bean
    @ConditionalOnBean(MyDependencyBean.class)
    public MyBean myBean() {
        return new MyBean();
    }
}

@ConditionalOnJava

  • application이 돌아가는 java의 버전이 충족되어야 생성된다.
@Configuration
public class MyConfiguration {

    @Bean
    @ConditionalOnJava(JavaVersion.EIGHT)
    public MyBean myBean() {
        return new MyBean();
    }
}

@ConditionalOnWebApplication, @ConditionalOnNotWebApplication

  • 애플리케이션이 웹 애플리케이션인지 여부에 따라 빈을 생성합니다.

4. 자동 설정(Auto Configuration)

docs.spring.io

  • classpath에 추가된 jar 의존성을 기반으로 스프링 애플리케이션을 자동으로 설정하는 기능
  • @Configuration 클래스에 @EnableAutoConfiguration 또는 @SpringBootApplication 을 추가하면 자동 설정이 활성화된다.(둘 중 하나만 사용)

@SpringBootApplication

다음의 세가지 기능을 활성화한다.

  • @EnableAutoConfiguration
    자동 설정 기능을 활성화하는 핵심 어노테이션

  • @ComponentScan
    애플리케이션이 위치한 패키지를 기준으로 @Component가 붙은 클래스들을 스캔하여 빈으로 등록한다.

  • @SpringBootConfiguration
    추가적인 빈을 등록하거나 다른 설정 클래스를 가져올 수 있게 해준다.
    통합 테스트에서 설정 탐지(configuration detection)를 돕는 스프링의 표준 @Configuration을 대체한다.

0개의 댓글