본문 바로가기

Spring22

메시지/국제화 스프링은 기본적인 메시지 관리 기능을 제공. 메시지 관리 기능을 사용하려면 스프링이 제공하는 MessageSource 를 스프링 빈으로 등록하면 되는데, MessageSource 는 인터페이스이다. 따라서 구현체인 ResourceBundleMessageSource 를 스프링 빈으로 등록하면 된다. 여기서 스프링 부트는 자동으로 MessageSource를 스프링 빈으로 등록한다. MessageSource 를 스프링 빈으로 등록하지 않고, 스프링 부트와 관련된 별도의 설정을 하지 않으면 messages 라는 이름으로 기본 등록된다. 따라서 messages_en.properties , messages_ko.properties , messages.properties 파일만 등록하면 자동으로 인식된다 messag.. 2024. 4. 22.
스프링 AOP 2 @Aspect AOP 스프링 애플리케이션에 프록시를 적용하려면 포인트컷과 어드바이스로 구성되어 있는 어드바이저를 만들어서 스프링 빈으로 등록하면 된다. 이 외의 모든 과정들은 자동 프록시 생성기가 처리해준다. 자동 프록시 생성기는 스프링 빈으로 등록되어 있는 어드바이저들을 찾고 해당 조건들을 만족하는 빈들에게 프록시를 적용해준다. 스프링은 @Aspect 애너테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어있는 어드바이저를 생성할 수 있게끔 지원한다. 자동 프록시 생성기의 두 가지 담당 기능 1. @Aspect를 보고 어드바이저임을 인지한 뒤 변환한다. @Aspect를 어드바이저로 변환해서 저장하는 과정 1. 실행: 스프링 애플리케이션 로딩 시점에 자동 프록시 생성기를 호출한다. 2. 모든 @Asp.. 2023. 8. 2.
스프링 AOP 1 애플리케이션의 핵심기능과 부가기능 핵심기능: 해당 객체가 제공하는 고유의 기능. 부가기능: 핵심 기능을 보조하는 기능. 로그, 트랜잭션 등 단독으로 사용되지 않고 핵심 기능에 편리성을 제공하는 역할 부가기능을 모든 핵심 기능 계층에 적용하기 위해 각 계층마다 부가기능 로직을 작성하는 것은 매우 비효율적이다. 만약 해당 클래스가 100개라면 부가기능을 100번 작성해야한다. 더 큰 문제는 해당 부가기능에 변경 사항이 생기게 된다면 부가기능을 일일이 작성한 경우, 해당 로직들을 찾아 전부 수정해야한다는, 생각만 해도 끔찍한 일이 발생한다. Proxy 생각만 해도 끔찍한 상황을 막기 위해 부가기능을 한 곳에 몰아넣고, 실제 핵심기능이 호출되기 전 후에 부가기능을 실행시킨 후 핵심기능을 호출할 수 있는 프록시가.. 2023. 7. 31.
DB 접근 4 - Transaction 사용 시 주의사항, Transaction 전파 Transaction 적용 위치 스프링에서 우선순위는 항상 더 구체적이고 자세한 것이 높은 우선순위를 가진다(Bean의 우선순위를 생각해보면 쉽게 알 수 있다) 메서드 > 클래스 > 인터페이스. 참고로 스프링은 인터페이스에 @Transactional을 사용하는 방식을 권장하지 않았지만, 스프링 5.0에서 해당 부분을 많이 개선했다. 과거에는 구체 클래스를 기반으로 프록시를 생성하는 CGLIB 방식을 사용했기 때문에 인터페이스에 있는 @Transactional을 인식하지 못하는 경우도 있었다. 하지만 이 부분은 5.0 이후 인터페이스의 @Transactional도 인식하는 방식으로 개선되었다. 그래도 이왕이면 공식 메뉴얼의 가이드라인에 따라 구체 클래스에 @Transactional을 사용하는 방식을 사용하.. 2023. 7. 14.
DB 접근 3 - Transaction 추상화, Exception 추상화 Transaction 추상화 서비스 계층은 가급적 특정 기술에 의존하지 않고 순수 자바 코드로 비즈니스 로직을 작성하는 것이 바람직하다. 하지만 위의 트랜잭션 과정은 서비스 계층이 특정 기술에 매우 종속적으로 작성할 수밖에 없다. JDBC 구현 기술을 사용해도 결국 서비스 계층은 해당 JDBC 구현 기술에 의존해야하고 이는 자바 코드로 순수하게 작성한 비즈니스 로직이 아니다. 또한 같은 트랜잭션을 유지하기 위해서 동일 커넥션을 파라미터로 넘겨야 하는 과정도 까다롭다. 그리고 데이터 접근 계층에서 발생할 수 있는 JDBC 구현 기술 예외가 서비스 계층으로 전파된다. 해당 SQLException은 Checked Exception이기 때문에 JDBC 구현 기술을 직접 호출한 Service 계층에서 처리하거나 .. 2023. 7. 13.
DB 접근 2 - JDBC, 커넥션풀, Transaction 1.커넥션 연결 - TCP/IP 2,SQL 전달 - DB가 해석할 수 있는 SQL을 연결된 커넥션을 통해 전달 3.결과 응답 - 전달된 SQL을 수행하고 결과 반환, 서버는 해당 결과 활용 이러한 연결방식은 각각의 DB마다 커넥션 연결방법, SQL 전달 방법, 결과 반환 방법이 다르기 때문에 해당 DB를 교체하게 될 경우 전체 코드를 수정해야하는 큰 문제가 발생할 수 있다. 또, 개발자가 각각의 데이터베이스마다 변하는 설정들을 새로 학습해야하는 단점도 있다. 이러한 상황에서 자바에서 데이터베이스에 접속할 수 있도록 하는 자바 API가 바로 JDBC이다. JDBC는 데이터베이스에서 자료를 쿼리하거나 업데이트 하는 방법을 제공한다. JDBC 표준 인터페이스 Connection - 연결 Statement - .. 2023. 7. 13.
JPA 8 - Querydsl Querydsl @Test // 기존 JPQL public void startJPQL() { //member 1 find String qlString = "select m from Member m " + "where m.username = :username"; Member findMember = em.createQuery(qlString, Member.class) .setParameter("username", "member1") .getSingleResult(); assertThat(findMember.getUsername()).isEqualTo("member1"); } @Test // Querydsl public void startQuerydsl() { // QMember m = new QMember(.. 2023. 7. 12.
JPA 7 - 스프링 데이터 JPA 기존에 스프링 빈, MVC를 공부했을 때 Repository 계층의 CRUD를 모두 직접 코드로 구현했었다. 하지만 이노베이션 캠프에서 사용하는 Repository는 단순히 JpaRepository를 상속받는 인터페이스만으로 구현하는 코드 없이 모든 CRUD를 실행할 수 있었다. 뿐만 아니라 찾고자 하는 엔티티의 필드를 쿼리 메서드방식으로 선언부만 적어주면 알아서 구현된다. 이런 말도 안되는 일이 어떻게 가능한지, ' 왜 이게 되는거지? ' 라는 생각을 할 수 밖에 없었다. 일반적인 상식선에서 이게 가능한가 싶은 기능은 스프링 데이터 JPA였고, 해당 스프링 데이터 JPA에 익숙해지기 보다는, 그 뿌리인 JPA에 대해서 충분히 공부해야겠다는 생각이 들었다. 스프링 데이터 JPA의 원리에 대해서 알고 싶은.. 2023. 7. 10.
JPA 6 - 성능 최적화 엔티티 직접 반환 X 엔티티에 @RequestBody를 직접 매핑하게 되면 해당 엔티티에 @NotEmpty와 같은 UI와 직접적인 연관이 있는 로직이 추가된다. 해당 엔티티와 관련된 다양한 API가 만들어질 때 각각의 API를 위한 모든 요청사항을 엔티티에 담기는 매우 어려움. 뿐만 아니라 엔티티가 변경되면 해당 엔티티를 매핑하여 사용하는 API의 스펙이 변하게 된다. 따라서 엔티티를 직접 사용하는 게 아닌 DataTransferObject, 즉 값을 담기 위한 용도를 가진 DTO를 생성해서 해당 DTO를 이용한다. dto로 반환할 필요. ManyToOne, OneToOne 조회 성능 최적화 version 1 별다른 조치 없이 지연로딩을 유지한 채로 반환하게 되면 처음 엔티티에 대한 쿼리가 작성되고 해당.. 2023. 7. 8.
JPA 5 - 패치 조인 경로 표현식 - .(점)을 찍어 객체 그래프를 탐색하는 것 Select m.username from Member m join m.team t join m.orders o where t.name = '팀A' m.username = 상태 필드, 단순히 값을 저장하기 위한 필드 경로탐색의 끝, 추가적인 탐색 불가능 m.team t = 단일 값 연관 필드, 연관관계를 위한 연관 필드(@ManyToOne, @OneToOne, 대상이 엔티티) 묵시적 내부 조인, 추가적인 탐색 가능 m.orders o = 컬렉션 값 연관 필드(@OneToMany, @ManyToMany, 대상이 컬렉션) 묵시적 내부 조인, 추가적인 탐색 불가능 단, from 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색이 가능 Selec.. 2023. 7. 3.