본문 바로가기

백/spring boot

스프링 빈

Spring Bean

Spring Bean이란

  • Bean : 스프링 컨테이너에 의해 인스턴스화되고, 조립되고, 관리되는 객체
  • Spring Bean : 스프링 컨테이너에 등록된 객체. 주로 @Bean, @Component, @Service 같은 어노테이션을 붙여 특정 객체를 빈으로 등록한다.

Spring Bean의 Life Cycle

스프링 컨테이너 생성 → Bean의 생성 → 의존성 주입 → 초기화 콜백 → Bean의 사용 → 소멸 전 콜백 → 스프링 종료

초기화 콜백 : 애플리케이션 서버가 시작될때 DB 와 연결설정하는 등 외부 자원과의 연결을 설정

소멸 전 콜백 : 서버 종료 시 DB연결 미리 끊는 종료 작업

  • 빈 생명주기 콜백 관리 방법은 3가지

    • 인터페이스 (InitializaingBean, DisposableBean 이용)
    public class ExampleBean implements InitializingBean, DisposableBean {
         @Override
         public void afterPropertiesSet() throws Exception {
             // 초기화 콜백
         }
          @Override
          public void destroy() throws Exception {
              // 소멸 전 콜백
          }
      }
    
    
     
    • 설정 정보에 초기화 메소드, 종료 메소드 지정
    • public class ExampleBean {
           public void initialize() throws Exception {
               // 초기화 콜백 (의존관계 주입이 끝나면 호출)
           }
            public void close() throws Exception {
                // 소멸 전 콜백 (메모리 반납, 연결 종료와 같은 과정)
            }
        }
         
         
        @Configurationclass LifeCycleConfig {
              @Bean(initMethod = "initialize", destroyMethod = "close")
              public ExampleBean exampleBean() {
                  // 생략
              }
          }
      
      
       
    • @PostConstruct, @PreDestroy 어노테이션 사용 → 가장 권장되는 방법 !
    • public class ExampleBean {   
      
      //초기화 콜백  
      @PostConstruct    
      public void initialize() throws Exception {}     
      
      //소멸 전 콜백
      @PreDestroy    
      public void close() throws Exception {}
      }
      
      
       

Spring Annotation

1. 어노테이션이란?

  • 프로그램에게 추가적인 정보를 제공해주는 메타데이터 (데이터를 위한 데이터)

2. 용도

  • 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보 제공
  • 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보 제공
  • 실행 시 (런타임) 특정 기능을 실행하도록 정보 제공

3. 어노테이션 종류

  1. JDK 표준 어노테이션ex) @Override, @Deprecated, @SuppressWarnings
  2. : 자바에서 기본적으로 제공하는 어노테이션
  3. meta 어노테이션
    • @Retention : 어노테이션의 정보를 어느 범위까지 유지할 지 결정
      • RetentionPolicy.SOURCE : 컴파일 전까지만 유효하며 컴파일 이후에는 사라짐
      • RetentionPolicy.CLASS : 컴파일러가 클래스를 참조할 때까지 유효
      • RetentionPolicy.RUNTIME : 컴파일 이후에도 JVM에 의해 계속 참조 가능. 즉, Java로 작성한 코드가 돌아가는 동안에 계속 유지된다
    • @Target : 생성할 어노테이션이 적용될 수 있는 위치를 나열
      • ElementType.TYPE : 클래스, 인터페이스, enum에만 어노테이션 사용가
      • ElementType.METHOD : 메소드 선언시 어노테이션 사용 가능
    • @Documented : 어노테이션 정보가 javadoc 문서에 포함되도록 한다
    • @Inherited : 하위 클래스가 어노테이션을 상속받을 수 있도록 한다
    • @Repeatable : 반복적으로 어노테이션을 선언할 수 있다
  4. : 어노테이션을 정의할 때 사용되는 어노테이션으로, 어노테이션을 위한 어노테이션이다
  5. 커스텀 어노테이션
    @Target({ElementType.[적용대상]})
    @Retention(RetentionPolicy.[정보유지 범위])
    public @interface [어노테이션명]{
    	public 타입 elementName() [default 값]
        ...
    }
    
     

    스프링 빈 등록방법

  6. : 사용자가 메타 어노테이션을 이용하여 직접 구현한 어노테이션

1. 빈을 수동으로 등록 - @Bean 과 @Configuration 이용하기

@Configuration
public class ResourceConfig {

    @Bean
    public myBean myBean() {
        return new myBean();
    }

}
 

설정 클래스 파일에 @Configuration 어노테이션을 적용해주고, 그 안에서 스프링 빈으로 등록하고싶은 메소드에 대해 @Bean 어노테이션을 적용시켜주면 스프링 컨테이너에 빈이 등록된다.

  • 과정 : 스프링 컨테이너는 @Configuration이 붙어있는 클래스를 자동으로 빈으로 등록해주고, 해당 클래스를 파싱해서 @Bean이 있는 메소드를 찾아 빈을 생성한다.
  • @Bean을 사용하는 클래스에는 반드시 @Configuration 어노테이션을 활용해서 해당 클래스에서 빈을 등록하겠다고 명시해주어야 한다.→ 싱글톤이란? : 어떠한 객체를 단 한 번만 생성하고, 생성된 객체를 어디서든지 참조할 수 있도록 하는 패턴
  • → @Bean 객체가 싱글톤으로 등록됨을 보장받기 위해

2. Bean을 자동으로 등록 - @Component 이용하기 → 권장!

스프링은 Component Scan을 사용해 @Component 어노테이션이 있는 클래스들을 찾아 자동으로 빈으로 등록해준다.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

    @AliasFor(annotation = Component.class)
    String value() default "";

    boolean proxyBeanMethods() default true;

}
 

@Configuration의 하위 어노테이션으로 @Configuration, @Repository, @Service, @Controller, @RestController 등이 있다.

@Bean과 @Component의 차이점

  • @Bean은 메소드에 적용시키고, 개발자가 직접 변경하기 어려운 대상(외부 라이브러리)에 사용하는 것이 권장됨
  • @Component는 클래스에 사용하고, 개발자가 직접 변경이 가능한 대상에 사용

컴포넌트 스캔의 동작과정

@ComponentScan이란?

@ComponentScan 어노테이션이 작성된 패키지 이하의 모든 클래스들을 순회하여 @Component 어노테이션이 붙은 클래스들을 스캔하여 빈을 찾아 Spring Container에 등록한다. 스프링부트에서는 @SpringBootApplication이 @ComponentScan을 들고있다.

스프링부트는 @SpringBootApplication 어노테이션이 선언된 클래스의 패키지 및 그 하위 패키지만 스캔하기 때문에 내가 생성하는 클래스들을 @SpringBootApplication 어노테이션이 선언된 클래스가 속한 패키지 내에 있도록 해주어야 한다.

위 사진과 같으면 클래스들이 @Application이 속한 com.ceos20.spring_boot 패키지 내에 있지 않아 내가 생성한 클래스들을 스캔하지 못하여 오류 생긴다.

따라서 com.ceos20.spring_boot 패키지 내에 클래스들이 위치하도록 해주어야 한다.

@ComponentScan 옵션

  1. @ComponentScan의 탐색 범위를 직접 지정할 수 있다.
@ComponentScan(basePackage = "경로")
 

basePackage : 탐색할 패키지의 시작위치. 하지만 default 방식(@SpringBootApplication이 존재하는 패키지)을 권장한다.

  1. includeFilters & excludeFilters
  • includeFilters : ConponentScan의 대상이 아니지만, ComponentScan에 포함시켜야 하는 경우에 사용
@ComponentScan(
     includeFilters = {
          @Filter(type = FilterType.상수, classes = 클래스명.class) })
 
  • excludeFilters : ConponentScan의 대상이지만, ComponentScan에서 제외시켜야 하는 경우에 사용
```
@ComponentScan(
     excludeFilters = {
          @Filter(type = FilterType.상수, classes = 클래스명.class) })
```
 

FilterType종류

  • ANNOTATION : 주어진 어노테이션이 명시된 컴포넌트를 필터
  • ASSIGNABLE_TYPE : 주어진 타입을 필터
  • ASPECTJ : AspectJ 패턴을 사용하여 필터
  • REGEX : 정규식을 이용한 필터
  • CUSTOM : 직접 만든 필터를 이용한 필터@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Ignore.class))
  • ex) Ignore라는 어노테이션이 붙인 빈들은 스캔에 포함시키지 않으려면 아래와 같이 필터링 할 수 있다.

@ComponentScan 동작과정

ClassPathBeanDefinitionScanner : 클래스 경로 내의 컴포넌트를 스캔하고 이를 Bean Definition객체로 변환하는 기능을 수행한다.

  1. @ComponentScan 어노테이션에 지정된 basePackages 속성을 통해 어떤 패키지 하위에서 빈을 스캔할지 확인
  2. base-package 하위의 모든 클래스들을 로딩하여 빈 후보인지 확인
  3. 빈 후보라면 Bean Definition(스프링 컨테이너가 해당 빈을 생성하고 관리하는데 필요한 모든 정보) 을 생성
  4. 이 정를 토대로 빈을 생성하게 된다.



' > spring boot' 카테고리의 다른 글

Base Entity 구현  (0) 2024.09.29
JPA 관련 문제들 (주로 N+1문제)  (0) 2024.09.29
IoC/DI, AOP, PSA  (0) 2024.09.29
Spring Security2 - 로그아웃  (0) 2024.08.16
spring security2 - refresh토큰 서버측 저장  (0) 2024.08.16