programming/java, spring (8) 썸네일형 리스트형 스프링 컨테이너와 IoC 바우처 미션을 진행하면서 근본적인 궁금증이 생겼다. 왜 의존성 주입을 받아야하지? java의 다형성을 통해 충분히 유연한 코드를 작성할 수 있고, 객체 간의 역할을 나눠서 수행하는 거라면 그냥 객체를 생성해서 할 수 있지 않을까? VoucherConfig voucherConfig = new VoucherConfig(); CommandHandler commandHandler = voucherConfig.commandHandler(); VoucherRepository voucherRepository = voucherConfig.voucherRepository(); 이제 Bean으로 등록해 사용해보자. ApplicationContext context = new AnnotationConfigApplication.. Java의 constant pool Constant Pool은 Java의 메모리 영역 중 하나로, String 리터럴들이 저장되는 풀이다. String 리터럴은 코드에 직접 작성된 문자열을 의미하며, 메모리 내에서 재사용될 수 있도록 관리된다. 따라서 같은 리터럴 값을 가지는 String 변수들은 Constant Pool 내에서 같은 객체를 참조하게 된다. 예를 들어, 다음과 같은 코드에서 String a = "hello world"; String b = "hello world"; 위의 경우, "hello world"라는 리터럴은 Constant Pool에 저장되며, 변수 a와 b는 같은 String 객체를 참조하게 된다. 따라서 a == b는 true다. 그러나, 다음과 같이 String 객체를 연결하는 경우에는 새로운 String 객체.. 트랜잭션 격리수준과 JPA 낙관적 락을 통한 동시성 제어 트랜잭션 격리수준(Transaction Isolation Level) 트랜잭션 격리수준은 동시에 실행되는 트랜잭션들 사이에서 어느 정도의 격리를 유지할지를 결정하는 것이다. 격리수준이 높을수록 동시성 문제가 발생할 가능성이 줄어든다. 트랜잭션 격리수준은 크게 네 가지로 구분할 수 있다. 1.READ UNCOMMITTED 가장 낮은 격리 수준 트랜잭션에서 수정 중인 데이터에 대해서도 다른 트랜잭션에서 읽기가 가능함 데이터의 일관성이 보장되지 않음 2.READ COMMITTED 다른 트랜잭션이 커밋한 데이터만 읽을 수 있음 트랜잭션에서 수정 중인 데이터는 다른 트랜잭션에서 조회 불가 Dirty Read 문제를 해결할 수 있음 UNREPETABLE READ 발생 3.REPEATABLE READ 한 트랜잭션 내.. Hibernate 내부 클래스 PersistentBag JPA 구현체인 Hibernate는 엔티티와 컬렉션을 매핑할 때 PersistentBag 객체로 매핑한다. 왜 그럴까? PersistentBag은 Hibernate의 컬렉션 지연 로딩(Lazy Loading) 기능을 지원하기 위해 사용된다. Hibernate에서는 연관된 엔티티들을 가져올 때, 지연 로딩 기능을 사용하여 필요한 시점에 데이터를 가져오도록 할 수 있다. 이를 위해, PersistentBag은 실제로 데이터베이스에서 데이터를 가져오는 것이 아니라, 데이터베이스 쿼리를 실행하기 위한 지연 로딩 기능을 제공한다. 따라서, Hibernate에서는 PersistentBag 객체를 사용하여 엔티티와 컬렉션을 매핑함으로써, 지연 로딩 기능을 지원하고, 컬렉션 연산을 처리할 수 있도록 한다. 실제 구현 .. Spring Security 인증 내부를 파헤쳐보자 Spring Security에서는 별도의 설정이 없다면 세션을 이용하여 처리한다. 즉, 사용자가 로그인을 하면 서버는 해당 사용자의 세션을 만들고, 서버의 메모리와 데이터베이스에 저장한다. Redis를 도입하여 세션을 관리하기로 결정하고, Spring Security 내부에서 어떻게 세션정보를 담고 있는지 궁금해졌다. SecurityContext 객체를 저장하고 감싸고 있는 wrapper 클래스인 SecurityContextHolder가 있고, Authentication 객체가 저장되는 보관소인 SecurityContext가 있다. 사용자의 세션 정보는 이 Authentication 객체 안에 담겨있다. 눈으로 직접 확인해보기 위해 코드로 살펴보자. ecurityContextHolder에서 Authent.. jacoco를 적용해 테스트 커버리지를 높여보자 계기가 된 건 토스뱅크 이응준님의 테스트 커버리지 100% 영상을 보고 난 후이다. 테스트코드를 작성하는 것이 적은 공수가 들어가는 것이 아니라는걸 알고 있었기 때문에 이걸 도전한다는 것에 큰 영감을 받았고, 크기가 커지면서 생기는 이슈를 해결하는 과정 또한 흥미로웠다. 얼마만큼의 코드를 자동화한 단위 테스트로 계산해야 할까? 대답할 필요조차 없다. 모조리 다 해야 한다. 모.조.리! 100% 테스트 커버리지를 권장하냐고? 권장이 아니라 강력히 요구한다. 작성한 코드는 한 줄도 빠짐없이 전부 테스트해야 한다. 군말은 필요 없다. ― 클린 코더 (로버트 마틴 저) 테스트코드의 중요성은 원래 알고있었다. 리팩토링 할 때 심리적 안정감을 느낄 수 있고, 클래스 간의 결합 관계에 대해 더욱 파악이 쉬워지고, 그.. Mockito로 테스트코드 작성하기 Mockito는 개발자가 동작을 직접 제어할 수 있는 가짜(Mock) 객체를 지원하는 테스트 프레임워크이다. 즉 한마디로 가짜로 객체 의존성을 주입하고, 원하는 결과를 stub하는 과정을 거쳐 단위테스트를 가능하게 해준다. @DisplayName("비즈니스 로직 -게시글") @ExtendWith(MockitoExtension.class) public class ArticleServiceTest { @InjectMocks private ArticleService sut; @Mock private ArticleRepository articleRepository; @DisplayName("게시글을 검색하면, 게시글 리스트를 반환") @Test void givenSearchParameters_whenSearch.. JPA Entity가 기본 생성자를 가져야 하는 이유 (정적 팩토리 메소드) JPA의 구현체인 hibernate에서 제공하는 다양한 기능을 활용하기 위해서는 public이나 protected 기본 생성자가 필요하다. Reflection API는 기본 생성자의 파라미터를 불러올 수 없기 때문에, 기본 생성자가 필요한 것이다. JPA는 매핑한 Entity를 조회할 때 class를 상속받은 Proxy 객체를 생성하기 때문에, private 생성자 대신 public, protected 기본 생성자가 있어야 한다. @Entity public class Article() { protected Article() {} } 정적 팩토리 메소드 Java Reflection API(구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 Java API, 컴.. 이전 1 다음