스프링 컨테이너와 스프링 빈

스프링 컨테이너

BeanFactory

스프링 컨테이너의 최상위 인터페이스

스프링 빈을 관리/조회 역할 담당

getBean() 제공 : 주어진 이름과 타입을 가진 bean 찾아 반환

ApplicationContext

ApplicationContext는 인터페이스이며 이를 스프링 컨테이너라고 한다.

BeanFactory의 기능을 모두 상속받아 제공(BeanFactory Interface의 구현체)

BeanFactory vs ApplicationContext
애플리케이션을 개발할 때는 빈을 관리, 조회하는 기능 외에도 필요한 부가기능들이 있음
ApplicationContext는 메세지소스, 환경변수, 애플리케이션 이벤트, 편리한 리소스 조회 같은 다양한 인터페이스를 상속

사용예

ApplicationContext context1 = new GenericXmlApplicationContext("classpath: applicationContext.xml");
BeanType bean = (BeanType) context.getBean("beanName");

ApplicationContext context2 = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanType bean = (BeanType) context.getBean("beanName");

ApplicationContext context3 = new AnnotationConfigApplicationContext(ConfigClass.class);
BeanType bean = context.getBean("beanName", BeanType.class);

스프링 빈

Java

어노테이션을 이용하여 AppConfig.java Class를 작성한다. (생성자를 이용한 DI)

…
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService() {
    	return new MemberServiceImpl(memberRepository());
    }
    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(
            memberRepository(),
            discountPolicy());
    }
    @Bean
    public MemberRepository memberRepository() {
    	return new MemoryMemberRepository();
    }
    @Bean
    public DiscountPolicy discountPolicy() {
    	return new RateDiscountPolicy();
    }
}

 

@Bean

메서드 앞에 @Bean을 붙여주게 되면 이 method가 생성 및 반환하는 객체를 스프링 컨테이너에 스프링 빈으로 등록

해당 method의 이름을 스프링 빈의 이름으로 사용

@Bean(name="…") name속성을 통해 bean의 id지정 가능

빈 이름은 항상 다른 이름을 부여해야하함

 

@Configuration

해당 클래스를 스프링 빈 설정 정보로 사용하겠다는 의미

여기서 @Bean이 적힌 method는 모두 스프링 컨테이너에 등록

 

스프링 컨테이너 생성시

…
ApplicationContext applicationContext = 
	new AnnotationConfigApplicationContext(AppConfig.class);
    
MemberService memberService =
	applicationContext.getBean("memberService", MemberService.class);

long memberId = 1L;
Member member = new Member(memberId, "memberA", Grade.VIP);
memberService.join(member);
…

new AnnotationConfigApplicationContext(AppConfig.class)를 이용해 컨테이너를 생성한다.

getBean(빈이름, 타입)을 이용해 bean 객체 생성

 

xml

bean설정을 위한  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">
	<!-- Setter Method 방식으로 의존 객체 주입시 property로 생성자 인자 전달 -->
    <bean id="bean ID" class="생성할 bean 객체의 class 이름 (package 경로 포함)">
        <property name=" bean 의 property 이름">
        	<value>property 값</value>
        </property>
        <property name="bean 의 property 이름" ref="참조할 bean의 ID"/>
    </bean>
    <!-- 생성자 방식으로 의존 객체 주입시 contructor-arg로 생성자 인자 전달 -->
    <bean id="bean ID" class="생성할 bean 객체의 class 이름 (package 경로 포함)">
        <constructor-arg><value>생성자의 파라미터 값</value></constructor-arg>
        <constructor-arg><ref bean="참조할 bean의 ID" /></constructor-arg>
    </bean>
</beans>

<value>를 통해 전달되는 값은 기본적으로 String타입으로 간주됨

type속성을 이용하여 다른 타입으로 변환 가능

생성자 방식 vs setter 방식
생성자 방식은 Bean 객체 생성 시점에 모든 의존 객체가 주입됨
성능상 유리, NullPointException이 발생 가능성 낮음
생성자 인자가 많을 때는 순서 파악이 어려움

setterMethod의 경우 Bean객체가 생성된 후에 의존 객체가 주입됨
setter를 별도로 실행하므로 성능이 다소 저하될 수 있고
setter누락시 NullPointException발생 가능성 있음

 

해당 파일에 지정된 bean 객체를 획득하는 법

//컨테이너 생성
ApplicationContext ctx = new ClassPathXmlApplicationContext("파일명.xml");
//Bean 불러오기
BeanType bean1 = ctx.getBean("bean_id", BeanType.class);
BeanType bean2 = (BeanType) ctx.getBean("bean_id");

싱글톤 컨테이너

싱글톤 패턴

클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴

private생성자를 이용하여 외부에서 임의로 new 키워드를 사용하지 못하게 할 수 있음

 

싱글톤 패턴의 문제점은

구현 코드가 길어지고, 의존관계상 클라이언트가 구체 클래스에 의존

내부 속성 변경, 초기화가 어렵고 자식클래스 구현이 힘들다

 

싱글톤 컨테이너

스프링 컨테이너는 자동으로 객체 인스턴스를 싱글톤으로 관리

 

주의할 점은

싱글톤 객체는 상태를 유지하게 설계하면 안됨

특정 클라이언트에 의존적인 필드 / 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안됨

->동시적으로 일을 처리할 때 문제 발생됨

 

AppConfig에서 @Configuration을 붙였다면 AnnotationConfigApplicationContext에 의해 AppConfig도 스프링 빈이 된다.

해당 빈의 클래스 정보를 출력해보면 클래스 명 뒤에 xxxCGLIB가 붙는 것을 확인할 수 있다.

스프링이 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig 클래스를 상속받은 임의의 다른 클래스를 만들고 그 다른 클래스를 스프링 빈으로 등록한 것

'공부기록 > 스프링' 카테고리의 다른 글

스프링 view 구현 (jsp)  (0) 2023.05.23
스프링 HTTP Session 사용  (0) 2023.05.22
Spring MVC(2) - Form처리  (0) 2023.05.22
Spring MVC(1) - DispatcherServlet, Handler mapping, Controller  (0) 2023.04.25
스프링의 DI  (0) 2023.04.20
myoskin