GDG on Campus Backend-Spring 스터디 WIL
Week 2 - IoC 컨테이너와 스프링부트 자동 설정
Spring IoC Container
- 객체(Bean) 생성
- 객체들의 의존성 구성 및 조립(configures and assembles)
- 객체들의 전체 생명 주기 관리
기본 패키지
org.springframework.beans
org.springframework.context
스프링에서는 개발자가 아닌 IoC 컨테이너가 자바 객체(Beans) 생성과 생명주기 관리에 대한 제어권을 가진다.
How?
1. IoC 컨테이너는 XML, 자바 어노테이션, 또는 자바 코드로 작성된 configuration metadata를 읽어 어떤 객체를 생성하고, 구성하고, 조립해야 하는지에 대한 정보를 얻는다.
2. 그 후, IoC 컨테이너는 빈을 생성할 때 필요한 의존성을 주입한다.
BeanFactory
와 ApplicationContext
BeanFactory
와 ApplicationContext
는 IoC 컨테이너를 대표하는 두가지 인터페이스이다.
BeanFactory
는 IoC 컨테이너의 가장 기본적인 형태이며, ApplicationContext
는 BeanFactory
의 기능을 확장한 버전이다.
org.springframework.beans.factory.BeanFactory
org.springframework.context.ApplicationContext
BeanFactory
의 하위 인터페이스(Sub-interface)
BeanFactory
를 확장하며, 그 기능의 상위 집합(Superset)이다.
즉, BeanFactory가 제공하는 모든 기능을 포함한다.
더 많은 엔터프라이즈급 기능을 추가로 제공한다.
WebApplicationContext
와 같은 애플리케이션 계층별 컨텍스트 제공이러한 추가 기능들 때문에 개발자들은 일반적으로
BeanFactory
보다ApplicationContext
를 선호한다.
bealdung.com
geeksforgeeks.org
@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();
}
}
What is Annotation?
프로그램에 대한 데이터를 제공하는 메타데이터의 한 형태로, 프로그램에 대한 보충 정보를 제공하기 위해 사용된다. 어노테이션은 코드의 동작에 직접적인 영향을 주지 않으며, 컴파일된 프로그램의 동작을 변경하지 않는다.
@Component
스프링이 사용자 정의 빈을 자동으로 탐지할 수 있게 해준다.
<?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
태그는 스프링에게 어노테이션이 붙은 클래스에 대해 어디를 봐야할지 알려준다.@Component
, @Controller
, @Service
, @Repository
, @Autowired
등)@Component
public class UserService {
// user service code
}
<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>
빈의 이름, 스코프 등과 같은 정의 정보는 BeanDefinition
객체에 담겨 관리된다.
속성 | 설명 |
---|---|
Class | 인스턴스화할 빈의 클래스 |
Name | 빈의 이름 또는 ID |
Scope | 빈의 스코프(생명주기 범위) |
Constructor arguments | 생성자 주입에 사용될 인자 |
Properties | Setter 주입에 사용될 프로퍼티 |
Autowiring mode | 자동 의존성 주입 모드 |
Lazy initialization mode | 지연 초기화 여부 |
Initialization method | 초기화 콜백 메서드 |
Destruction method | 소멸 콜백 메서드 |
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();
}
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
Scope 기본값이 Singleton인 이유
서버환경에서 수많은 요청이 올때마다 객체를 생성하면 큰 오버헤드가 발생한다. 따라서 스프링은 싱글톤으로 bean을 생성한다.
싱글톤 패턴의 문제점
- private 생성자로 인해 상속할 수 없다.
- mock 객체로 대체하기 어려워 테스트가 어렵다.
- 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장할 수 없다. 여러개의 jvm 분산 → 독립적으로 객체 생성
- 전역 상태를 만들기 때문에 객체지향적이지 않다.
싱글톤의 static method를 이용해 언제든지 싱글톤에 접근할 수 있어 전역 상태로 사용될 수 있다.
스프링의 Singleton Registry
- Singleton pattern의 단점 보완
- 스프링 컨테이너(ApplicationContext)가 직접 bean을 singleton으로 관리한다.
- private 생성자가 필요없고 일반 자바 클래스처럼 설계 가능
컨테이너에 요청할 때마다 매번 새로운 인스턴스를 생성하여 반환
일반적으로 상태를 가지는(stateful) 빈에는 프로토타입 스코프를, 상태가 없는(stateless) 빈에는 싱글톤 스코프를 사용하는 것이 좋다.
Condition
인터페이스를 구현한 클래스를 만들어 빈 생성 로직을 직접 정의할 수 있다.@Configuration
public class MyConfiguration {
@Bean
@ConditionalOnProperty(name = "my.property.enabled", havingValue = "true")
public MyBean myBean() {
return new MyBean();
}
}
@Configuration
public class MyConfiguration {
@Bean
@ConditionalOnClass(name = "com.example.MyClass")
public MyBean myBean() {
return new MyBean();
}
}
ApplicationContext
에 이미 정의되어있지 않을 때만 생성한다.@Configuration
public class MyConfiguration {
@Bean
@ConditionalOnMissingBean(MyBean.class)
public MyBean myBean() {
return new MyBean();
}
}
ApplicationContext
에 이미 정의되어 있을 때만 생성한다.@Configuration
public class MyConfiguration {
@Bean
@ConditionalOnBean(MyDependencyBean.class)
public MyBean myBean() {
return new MyBean();
}
}
@Configuration
public class MyConfiguration {
@Bean
@ConditionalOnJava(JavaVersion.EIGHT)
public MyBean myBean() {
return new MyBean();
}
}
@Configuration
클래스에 @EnableAutoConfiguration
또는 @SpringBootApplication
을 추가하면 자동 설정이 활성화된다.(둘 중 하나만 사용)다음의 세가지 기능을 활성화한다.
@EnableAutoConfiguration
자동 설정 기능을 활성화하는 핵심 어노테이션
@ComponentScan
애플리케이션이 위치한 패키지를 기준으로 @Component
가 붙은 클래스들을 스캔하여 빈으로 등록한다.
@SpringBootConfiguration
추가적인 빈을 등록하거나 다른 설정 클래스를 가져올 수 있게 해준다.
통합 테스트에서 설정 탐지(configuration detection)를 돕는 스프링의 표준 @Configuration
을 대체한다.