본문 바로가기
spring

spring Bean 개념정리 1편(Spring 컨테이너, @Component,싱글톤, Swagger, Bean 조회)

by 토망이 2023. 5. 4.

본 글에서는 Spring Bean과 관련한 여러가지 개념들을 정리하였습니다.

 

이전 글에서 의존성 주입(DI)의 핵심 개념으로, Spring 컨테이너에 Bean을 등록하고, 이를 조회해서 객체에 주입하는 과정을 설명하였습니다. 

Spring 의존성 주입

 

Spring 의존성 주입(DI, Dependency Injection)

spring 관련 첫 글로 무엇이 좋을까 하다가, 의존성 주입에 대한 글을 쓰게 되었습니다. 가장 보편적인 케이스인 Controller라는 클래스에서 Service 클래스를 호출하는 코드를 통해 이해해보겠습니다.

dnl1029.tistory.com

 ---------------------------- 의존성 주입 핵심  ----------------------------

1. 본인 클래스가 호출되기 위해(사용되기 위해) spring 컨테이너에 Bean 등록

2. bean 등록된 클래스를 호출하기 위해서는, spring 컨테이너에 등록된 Bean을 조회해서, 객체에 주입해서 사용

--------------------------------------------------------------------------

 

위에서 Spring 컨테이너란 무엇을 의미하는 것인지 알아보겠습니다.

Spring 컨테이너를 단순하게 한줄로 정의하면 ApplicationContext라는 인터페이스라 할 수 있습니다. Spring 컨테이너 안에 존재하는 빈 저장소에, @Component를 통해서 등록된 Bean들과 Spring 구동시 기본적으로 사용하는 Bean들이 등록되어 있는데, 의존성 주입을 하려면 이 저장소에서 Bean을 꺼내와야 합니다. 

엄밀히 말하면 ApplicationContext는 BeanFactory라는 Spring 컨테이너의 최상위 인터페이스를 상속받은 개념입니다. 그러나 보통 BeanFactory를 직접 사용하지 않고, 여러 부가기능이 포함된 ApplicationContext를 사용하기 때문에, ApplicationContext가 곧 Spring 컨테이너라고 간주하고 이것만 사용해도 무방합니다.

Spring 컨테이너의 아주 중요한 특징으로, 객체 인스턴스를 싱글톤으로 관리한다는 특징이 있습니다. 즉, Spring 컨테이너에 @Component를 통해 빈으로 등록되면, 자동적으로 싱글톤이 보장됩니다. 단, 단순히 @Bean 을 통해 등록했을 경우에는 싱글톤이 보장되지 않을 수 있는데, 2편에서 추가로 다루겠습니다.

 

 

이제 코드를 통해 이해해봅시다. 이전글에서 다루었던 BeanTestController에다가 ApplicationContext(Spring 컨테이너)를 추가해보겠습니다. 아래와 같이 ApplicationContext를 추가하면, 현재 Spring 컨테이너에 등록된 모든 Bean들을 조회할 수 있습니다.

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("api")
public class BeanTestController {
    private final BeanTestService beanTestService;

    @Autowired
    ApplicationContext applicationContext;

    @GetMapping("/beanList")
    public void getBeanList() {
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for(String beanName : beanDefinitionNames) {
            log.info("beanName: {}",beanName);
        }
    }

    public void beanTest() {
        beanTestService.log();
    }
}

 

BeanTestController의 getBeanList()라는 메서드를 테스트하기 위해, Swagger UI를 사용하겠습니다. Swagger는 아래와 같이 pom.xml에 의존성만 추가해주기만 하면, 별다른 설정이 없어도 서버 구동후 swagger 웹페이지 url을 입력하여, 내가 작성한 Controller에서 @RequestMapping, @GetMapping 되어 있는 메서드들을 사용할 수 있습니다.

 

- 참고로 개발환경 세팅은 아래와 같이 하였습니다. https://start.spring.io/ 에서 Springboot 템플릿을 받아 사용하시면 됩니다. 글 조회 시점에 따라 springboot 버전 및 java 버전은 달라질 수 있습니다. 

------------------------ 아래 ------------------------

Project : Maven

Language : Java

Springboot 버전 : 3.0.6

java 버전 : 17

Packaging : Jar

의존성 : Spring Web, Lombok 

springdoc : 2.0.2(pom.xml에 수동으로 추가)

----------------------------------------------------------

 

아래와 같이 pom.xml에 springdoc의존성을 추가하면 바로  swagger를 사용할 수 있습니다.

<dependencies>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
   </dependency>
   <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
   </dependency>
   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
      <version>2.0.2</version>
   </dependency>
</dependencies>

 

의존성 추가후 IntelliJ 재시작, Springboot 서버를 아래와 같이 가동 후

 

swagger 웹페이지 주소(http://localhost:8080/swagger-ui/index.html)를 크롬에서 열면 아래와 같이 Swagger 화면이 뜹니다. 내가 만든 메서드를 클릭 후 Execute하면 실행할 수 있습니다. getBeanList() 메서드를 실행해봅시다. 

 

아래와 같이 내가 수동으로 @Component를 통해 등록한 beanTestController, beanTestService라는 명칭의 bean도 확인 가능하며,  spring에서 기본적으로 등록하는 bean들도 수십개가 조회됩니다. 해당 기능을 통해 Spring 컨테이너에 내가 의도한 bean이 등록되었는지, bean 명칭은 제대로 등록되었는지 등을 확인해 볼 수 있습니다. 

댓글