article thumbnail image
Published 2021. 7. 29. 21:21
728x90
반응형

Bean 생성 방식

Component Scanning

Spring IoC Container가 IoC Container를 만들고 그 안에 Bean을 등록할때 사용하는 Interface들을 Life Cycle Callback이라 부름

Life Cycle Callback 중에는 @Component이 붙어있는 모든 Class의 Instance를 생성해 Bean으로 등록하는 작업을 수행하는 Annotation Processor가 등록 돼있음

Instance 👉 일반적으로 실행 중인 임의의 프로세스, 해당 클래스의 구조로 컴퓨터 저장공간에서 할당되어 현재 생성된 Object를 의미

이때, @ComonentScan Annotation이 붙어있는 Class가 이에 해당

즉, @ComponentScan, @Component Anotation을 사용해서 Bean을 등록하는 방법

@ComponentScan은 어느 지점부터 Component를 찾으라고 알려주는 역할을 하고,

@Component는 실제로 찾아서 Bean으로 등록할 Class를 의미

 

@ComponentScan @Component이 부여된 Class를 찾아 자동으로 Bean으로 등록해주는 역할을 함

@ComponentScan이 붙어있는 Class가 있는 package에서부터 모든 하위 package의 모든 Class를 찾아 다니며,

@Component나 @Component를 사용하는 다른 Annotation을 사용하는 Class를 찾음
[EX] Stereotype Annotation(@Controller, @Service, @Repository 등)
Stereotype Annotation들은 내부적으로 @Component Annotation을 사용

 


Configuration

Configuration을 이용한 Bean 등록 방법은, XML에 설정하는 방법과 Java Class에 설정하는 방법이 있음
Bean 설정파일은 XML과 자바 설정파일로 작성할 수 있는데 일반적으로는 XML에 설정하지만, 최근 추세는 자바 설정파일을 좀 더 많이 사용

 


 

@Configuration 사용, @Bean 정의

먼저 Java class에서 @Configuration Annotation을 사용해서 직접 @Bean을 등록해주는 방법
일반적으로 xxxxConfiguration와 같이 명명

@Bean Annotation을 사용해 직접 Bean을 정의하면 자동으로 Bean으로 등록

이렇게 Bean을 직접 정의해서 등록하면 @Component Annotation을 붙이지 않아도 됨

@Configuration
public class ExampleConfiguration {
    @Bean
    public ExampleController exampleController() {
        return new ExampleController;
    }
}

exampleController()에서 리턴되는 객체(ExampleController)가 IoC Container 안에 Bean으로 등록

 

@Configuration Annotation을 보면 이 Annotation도 내부적으로 @Component를 사용하기 때문에 @ComponentScan의 검색 대상이 되고,
그에 따라 Bean을 정의한 @Configuration이 읽힐 때 그 안에 정의한 Bean들이 IoC Container에 등록되는 것

 


XML 파일에 설정

XML 파일에 직접 Bean을 등록하여 Application의 Bean을 설정하는 방법

 

XML 방식으로 Bean을 정의하는데 필요한 속성들은 아래와 같음

  • class(필수) : 정규화된 자바 class 이름
  • id : bean의 고유 식별자
  • scope : 객체의 범위 (sigleton, prototype 등)
  • constructor-arg : 생성 시 생성자에 전달할 인수
  • property : 생성 시 bean setter에 전달할 인수
  • init-method, destroy-method

기본적인 양식은 아래와 같음

<!-- A simple bean definition -->
<bean id="..." class="..."></bean>

<!-- A bean definition with scope-->
<bean id="..." class="..." scope="singleton"></bean>

<!-- A bean definition with property -->
<bean id="..." class="...">
	<property name="message" value="Hello World!"/>
</bean>

<!-- A bean definition with initialization method -->
<bean id="..." class="..." init-method="..."></bean>

실제 사용되는 예시는 아래와 같다.

<?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 http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <bean id="dog" class="com.spring.Dog">
        <property name="myName" value="poodle"></property>
    </bean>

    <bean id="cat" class="com.spring.Cat">
        <property name="myName" value="bella"></property>
    </bean>

    <bean id="petOwner" class="com.spring.PetOwner" scope="singleton">
        <constructor-arg name="animal" ref="dog"></constructor-arg>
    </bean>
</beans>

 


Bean Scope

Spring은 기본적으로 모든 Bean을 Singleton으로 생성하여 관리함
Singleton Bean은 Spring Container에서 한 번 생성 후, Container가 사라질 때 Bean도 제거
생성된 하나의 Instance는 Single Beans Cache에 저장되고, 해당 Bean에 대한 요청과 참조가 있으면 캐시된 객체를 반환
하나만 생성되기 때문에 동일한 것을 참조, 기본적으로 모든 Bean은 Scope가 명시적으로 지정되지 않으면 Singleton.

구체적으로는 Application 구동 시 JVM 안에서 스프링이 Bean마다 하나의 객체를 생성하는 것을 의미

그래서 Spring을 통해서 Bean을 주입 받으면 언제나 주입받은 Bean은 동일한 객체라는 가정하에서 개발함

Scope Description
singleton 하나의 Bean 정의에 대해서 Spring IoC Container 내에 단 하나의 객체만 존재
prototype 하나의 Bean 정의에 대해서 다수의 객체가 존재할 수 있음
request 하나의 Bean 정의에 대해서 하나의 HTTP request의 생명주기 안에 단 하나의 객체만 존재
즉, 각각의 HTTP reqeust는 자신만의 객체를 가짐
Web-aware Spring ApplicationContext 안에서만 유효함
session 하나의 Bean 정의에 대해서 하나의 HTTP Session의 생명주기 안에 단 하나의 객체만 존재 
Web-aware Spring ApplicationContext 안에서만 유효함
global session 하나의 Bean 정의에 대해서 하나의 global HTTP Session의 생명주기 안에 단 하나의 객체만 존재
일반적으로 portlet context 안에서 유효함

request, session, global session의 Scope는 일반 Spring Application이 아닌, Spring MVC Web Application에서만 사용

 


참고자료 👇

https://velog.io/@gillog/Spring-Bean-%EC%A0%95%EB%A6%AC

반응형
복사했습니다!