신입으로 입사한 후 제가 개발보다도 먼저 진행하게 된 업무는 다름 아닌 배포 자동화 구축이었습니다. 기존에 사용하던 블로그에 삽질했던 순간들을 기록했었지만, 최근에 도커 컨테이너 환경으로 마이그레이션 하면서 신입 때의 기억도 더듬어보고 포스팅도 현재의 기록으로 리팩터링 하기 위해서 다시 작성하려고 합니다. 대표적인 배포 자동화 구축(CI/CD) 툴로는 젠킨스와 Git Action 등이 있지만, 회사에서 Git 프라이빗 저장소로 요나를 쓰고 있어서 젠킨스를 도입하게 되었습니다. 구축 당시에 배포 방식으로 BLUE/GREEN 무중단 배포 방식을 채택하고 싶었으나, 인프라 환경이 적절치 않아 단순한 구조의 배포 자동화임을 감안해서 봐주시면 감사하겠습니다!
Spring Security 시작하기
오늘은 간단한 예제 코드와 함께 Spring Security
에 대해 제가 학습한 내용을 다뤄보고자 합니다. 학습하게 된 계기를 이야기해 보자면, 제가 다니고 있는 회사에서는 Spring Security를 사용하지 않고 회원 시스템을 구축했고 이에 따라 겪었던 많은 불편함이 있었습니다. 로그인 로직에 의도를 알 수 없는 코드들이 엉켜 있다든지, 문서화나 도식화가 되어 있지 않아서 로직을 이해하는데에 많은 시간이 걸린다든지, 그리고 유저의 권한이나 세션을 검증하는 중복 로직들이 각 서비스 레이어에 존재했습니다. 저는 이런 문제들을 조금이라도 개선하기 위해서 인터셉터를 이용한 공통 모듈을 개발했었는데요, 그럼에도 Spring Security를 이용하는 것보다는 개발하는데 소요되는 리소스가 크고 XML로 설정하다 보니 가독성 측면에서도 이점을 가져가기에 어려웠습니다. 이런저런 다른 이유도 많았지만 다음에 이직하게 될 회사에서 사용할 수도 있고, 개인 프로젝트에서라도 적용해 볼 수 있도록 학습을 시작하게 되었습니다!
JPA란 무엇인가요?
오늘은 Java 진영의 ORM으로 많이 사용되고 있는 JPA 대해서 작성해 보고자 합니다. 제가 JPA를 처음 접한 건 약 2년 전입니다. 국비학원 교육을 받을 때 학원에서는 MyBatis를 가르쳤던 터라 JPA를 사용할 기회가 없었는데요, 교육 막바지에 학원의 협력 기업들과 실무에 관련된 프로젝트를 실제로 경험해 볼 수 있었는데, 그 때 기업 실무자의 권유로 JPA를 사용하게 되었습니다. 그 당시에도 이미 가장 많이 사용되고 있는 ORM이었고, 진행했던 프로젝트 기획도 엄청나게 복잡한 기능을 요구했던 게 아니었기 때문에 JPA를 충분히 고려해 볼 만했습니다. 물론 당시에는 이런 이유들이 와닿지는 않았지만요. 그렇게 JPA를 이해하고 썼다기보다는 비슷한 기능을 구현한 사람들의 래퍼런스들을 찾아가며 카피하기에 바빴던 것 같습니다. 이때까지만 해도 JPA의 필요성을 그다지 체감하지 못했습니다. 지금까지도 개인적인 공부 외엔 JPA를 사용해 볼 수 있는 기회가 없었고, 회사에선 MyBatis나 레거시 프로젝트인 경우엔 iBatis를 이용해서 개발해 왔습니다. 그러면서 들었던 생각은…
“JPA 쓰고 싶다!”
- 요구사항에 대한 대처가 쉽지 않았다.
- 컴파일 단계에서 기본적인 에러(잘못된 SQL 문법이나 오타)를 감지하지 않기 때문에 사소한 실수에 시간이 많이 소요되는 경우가 생긴다.
MySQL의 트랜잭션과 격리수준
우리에게 친숙한 트랜잭션은 작업의 완전성을 보장해줍니다! 쉽게 설명하자면 2개 이상의 작업이 있을 때 단 1개의 작업이라도 오류로 인해 정상적으로 처리되지 못할 경우 정상 처리된 작업까지도 원 상태로 복구하는 기능입니다. 예시로는 2개 이상의 작업을 이야기 했지만 실제로는 단 한개의 작업이라도 트랜잭션을 통해 작업의 완전성을 보장합니다. 현재 보편적으로 사용하는 데이터베이스 툴들은 AUTO COMMIT을 지원하고 있어서 트랜잭션을 인지하기가 어려운 것 같습니다. 하지만 데이터베이스를 다루는 개발자라면 내가 사용하는 데이터베이스는 어떻게 트랜잭션을 움직이고 있는지 알아야 상황에 맞는 대처를 할 수 있겠습니다.
추상 클래스를 이용해서 모델 설계하기
최근 회사에서 운영중인 서비스 하나가 리뉴얼을 시작하면서 새롭게 기초 설계를 할 수 있는 기회가 있었습니다. 저는 일해오면서 줄곧 OOP에 대한 아쉬움이 있었기 때문에 제가 맡은 부분에 한해서라도 최대한 OOP의 원칙을 지킨 코드들을 작성하고 싶었습니다. 리뉴얼 전 기존 서비스는 유사한 논리적인 구조를 가진 모델들이 많았고 그로 인해 중복코드 또한 많이 존재했습니다. 그러다보니 추가 요구사항이 오면 번거로운 작업들이 굉장히 많았는데요, 이를 개선하기 위해 추상 클래스를 사용해서 공통으로 가지는 필드들은 추상 클래스에서 관리하고 추가적인 요구사항에 유연하게 대처할 수 있도록 설계해 보고자 합니다!
Stream API를 이용해서 레거시 코드 리팩터링 하기
Stream API는 Java 8 버전에서 처음 등장했습니다. Java 21 버전까지 나온 현재는 이미 Stream API에 대한 정보들이 많이 있습니다. 그래서 Stream API를 사용하는 방법에 대해 작성하기 보다는 제가 회사에 존재하는 레거시 코드들을 Stream API를 이용해 어떻게 리팩터링 했는지, 그리고 어떤 결과를 얻게 되었는지 작성해보려고 합니다.