안녕하세요 오늘은 Spring Boot에서 사용하고 있는 디자인 패턴에 대해서 포스팅해보도록 하겠습니다.
Spring Boot에서 Spring Container는 기본적으로 싱글톤 패턴을 가집니다. 싱글톤 패턴이란 객체의 인스턴스가 오직 1개만 생성되는 패턴입니다. Spring Container는 그 정의를 느슨하게 해서 Spring Container 1개 당 하나의 Bean을 가지고 있습니다. 여러 객체를 생성하지 않기 때문에 메모리 측면에서 이점이 있으며 다른 객체 간에 데이터 공유가 쉽다는 장점이 있으나 구현 코드가 복잡하며 테스트하기 어렵다는 단점이 있습니다. 하지만 Spring Boot에서는 관련 부분을 사용자가 직접 진행할 필요가 없어 싱글톤 패턴의 단점이 많이 상쇄됩니다.
출처
: https://dev-aiden.com/spring/Spring-Container/
: https://metaforeverything.tistory.com/19
Spring Container의 패턴 변경 및 기타 설정은 BeanDefinition이라는 추상화에서 관리합니다. 어떠한 설정 파일을 사용하더라고 BeanDefinition 형식의 메타 정보를 생성해주고 Spring Container는 설정 파일의 형식과 상관없이 BeanDefinition을 통해 Bean의 정보를 알아내서 메타 정보를 기반으로 인스턴스가 생성됩니다. BeanDefinition의 scope 설정의 경우 default가 싱글톤으로 되어 있기 때문에 만약 싱글톤 패턴을 변경하고 싶다면 이 부분을 변경하면 됩니다.
출처 : https://bcp0109.tistory.com/367
ApplicationContext의 경우 팩토리 메소드 패턴을 가집니다. 팩토리 메소드 패턴이란 객체를 생성할 때 어떤 클래스의 인스턴스를 만들 지 자식 클래스에서 결정하게 하는 패턴입니다. 객체 생성 직접 호출들을 팩토리 메서드에 대한 호출로 대체하여 팩토리 메서드 내에서 객체를 호출합니다. ApplicationContext 객체의 경우 팩토리 역할을 하여 Bean에 의존성 주입을 진행할 때 ApplicationContext 내의 getBean() 팩토리 메소드를 이용합니다. 이를 통해 객체를 확장할 때 기존 코드의 변경 없이 안정적으로 서비스를 유지할 수 있습니다.
Spring Boot에서는 CGLib을 이용하여 Bean 객체를 프록시로 매핑하는 프록시 패턴을 가집니다. 프록시 패턴이란 어떤 객체를 사용하고자 할 때 객체를 직접적으로 참조하는 것이 아닌 해당 객체와 대응하는 객체를 통해 대상 객체에 접근하는 방식입니다. 이를 통해 해당 객체가 메모리에 존재하지 않아도 기본적인 정보를 참조하거나 설정할 수 있으며 실제 객체 기능이 필요한 시점까지 객체의 생성을 미룰 수 있습니다. Spring Boot에서는 @Transactional 어노테이션 내의 invokeWithinTransaction() 메소드를 통해 프록시를 설정할 수 있습니다.
Spring JDBC 내의 JdbcTemplate는 템플릿 메소드 패턴으로 동작합니다. 템플릿 메소드 패턴이란 어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화하여 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴입니다. 즉 여러 객체가 동일한 구조로 동작할 때 기본 구조에 대한 내용을 일괄적으로 관리하면서 각 객체 별로 달라지는 부분들에 대해서 따로 만들고 싶을 때 사용됩니다. JdbcTemplate는 MySQL, MariaDB 등 여러 DB와 연결을 진행하지만, 기본적인 동작 구조는 다음의 4단계로 동일합니다.
따라서 다른 DB 드라이버 별로 달라지는 부분만 따로 만들고 기본 구조에 대한 내용을 일괄적으로 관리하게 되어 중복 코드가 줄어들며 자식 클래스의 역할이 줄어들어 핵심 로직의 관리가 용이합니다.
이상으로 Spring Boot에서 사용되는 디자인 패턴들에 대해 알아보았습니다. 긴 글 읽어주셔서 감사합니다!