본문 바로가기

Spring&SpringBoot31

Step5. 자동 프록시 생성기와 포인트컷 표현식 개선 목표 스프링 팩토리 빈을 사용하여 타깃과 부가기능의 조합마다 Handler 클래스가 만들어지던 문제를 해결했다. 하지만 빈 설정 정보에는 타깃과 어드바이저 조합마다 설정이 중복된다. 어드바이저 등록 설정은 똑같은데 타깃만 달라지는 설정 정보 중복이 발생하는 것이다. 설정 중복을 제거하기 위해 팩토리 빈을 스프링 빈으로 등록하는 방법이 아닌 자동 프록시 생성기를 만드는 방법을 선택한다. transactionAdvisor 빈 후처리기 빈 후처리기는 스프링에 제공하는 확장 포인트다. 빈 후처리기를 빈으로 동록하여 사용한다. 빈 오브젝트가 생성될 때마다 빈 후처리기에 보내서 후처리 작업을 요청한다. 프록시에 적용하려면 빈 오브젝트가 생성될 때마다 빈 후처리기가 프록시 적용 여부를 판단하고, 프록시를 생성하.. 2023. 4. 20.
Step4. JDK 팩토리 빈을 추상화하는 스프링 팩토리 빈 스프링의 프록시 팩토리 빈 지금까지 알아본 프록시 생성 방법은 JDK가 제공하는 방법이다. JDK가 제공하는 프록시 팩토리 빈을 사용하면 InvokeHandler 구현 클래스가 기능 위임과 부가기능 적용 메소드 판별, 부가기능 수행 등 여러 책임을 가진다. 변경의 이유가 여러가지기 때문에 쉽게 변경되고, 확장에도 불리하다. 앞에서 살펴본 바로는 타깃에 따라 부가기능이 달라지면 새로운 InvokeHandler가 필요해서 중복 문제가 발생했다. 그렇다면 기능 위임과 부가기능 메소드 판별, 부가기능 수행이라는 책임을 각기 다른 객체에 할당하고, 서로 협력해서 다이나믹 프록시를 생성하도록 만들면 되지 않을까? 특히 부가기능 책임을 가진 객체를 타깃이라는 구현으로부터 분리해서, 다양한 타깃과 협력할 수 있도록 재.. 2023. 4. 11.
Step2&3. 다이나믹 프록시와 팩토리빈 프록시와 프록시를 사용하는 디자인 패턴 프록시는 클라이언트의 요청을 받아주는 대리인과 같은 역할을 하는 오브젝트이다. 이때 프록시는 클라이언트가 사용하려고 하는 실제 대상인 것처럼 위장한다. 그리고 프록시를 통해 최종적으로 요청을 위임받아 처리하는 실제 오브젝트를 타깃이라고 한다. 프록시를 사용하는 디자인 패턴은 프록시의 사용 목적에 따라 두 가지로 나뉜다. 데코레이터 패턴 : 타깃에 부가적인 기능을 부여 프록시 패턴 : 타깃의 접근 방법 제어 데코레이터 패턴과 디자인 패턴 둘다 프록시를 사용하기 때문에 구현에 DI를 사용한다는 점에서 유사하다. 하지만 데코레이터 패턴은 인터페이스를 통해서만 위임하는 방식이기 때문에 여러개의 부가기능을 체인처럼 연결하고, 각 데코레이터는 자신이 위임하는 인터페이스가 또다.. 2023. 4. 11.
Step1. 데코레이터 패턴을 적용하는 트랜잭션 코드 분리와 고립된 단위 테스트 트랜잭션 코드 분리 요구사항 비즈니스 로직을 담는 UserService에 여전히 트랜잭션 처리 코드가 남아있다. 이 트랜잭션 처리를 분리하는 작업을 해보자. 단, 클라이언트가 비즈니스 로직만 남도록 개선하더라도 UserService의 클라이언트는 트랜잭션이 적용된 기능을 사용할 수 있어야 한다. UserService에 트랜잭션을 적용한 upgradeLevels 코드를 살펴보면 크게 트랜잭션 관리(시작, 종료)와 비즈니스 로직(레벨 업그레이드) 부분으로 구분할 수 있다. 관심사도 다르고 주고받는 데이터도 없으므로 완전히 분리가 가능하다. 비즈니스 로직을 우선 메소드로 추출해보자. public void upgradeLevels() { // 트랜잭션 생성과 시작 TransactionStatus status =.. 2023. 4. 11.
6장 AOP part1 6장은 양이 많아서 이번 주는 1절부터 4절까지 읽었다. 이번주는 이해가 잘 안 됐던 주이기도 하다. 리플렉션에 대해서 들어보기는 했는데 이렇게 써보는게 처음이라 낯설기도 했고, 무엇보다 다이나믹 프록시가 자바 코드로 보이는 것이 아니니 생소했다. 그리고 양이 너무.. 많다.. 나의 언어로 바꾸느라 애를 먹었던 주이기도 하다. 6장은 서비스 코드에서 트랜잭션의 완전한 분리를 위해 개선해나가는 과정이다. 여기서 다이나믹 프록시도 사용되고 리플렉션도 나오고 전략 패턴이나 템플릿 콜백도 나온다. 아무튼 지금까지 배운 것의 총집합이었다. 이 포스팅에서는 part1의 큰 도약에 대해서만 요약한다. 6장 이해에 어려움을 겪으시는 분들께 도움이 되기를 🙏 목표 서비스의 트랜잭션 코드 분리. 확장 가능한 설계를 고려하.. 2023. 4. 11.
테스트에 서비스 추상화 적용하기 (feat. 테스트 대역, 테스트 스텁, 목 오브젝트) 사용자 레벨이 업그레이드되는 경우, 해당 사용자에게 이메일을 보내 알려주는 기능을 추가하기로 했다. 이메일 전송 메소드는 UserService의 upgradeLevels에서 호출된다. 메일 서비스 추상화의 목적 메일 서비스에 추상화 계층을 추가하면 테스트하기 어려운 JavaMail을 테스트하기 편리하게 만들어준다. 메일 서비스 테스트의 관심사 자바 프로그램에서 메일 보내기 기능을 구현하려면 JavaMail API를 사용해서 실제 메일 서버에 전송할 메일을 전달한다. 운영 환경에서는 직접 메일을 전송해야하지만, UserService의 upgradeLevels을 테스트하는 테스트 환경에서는 메일 전송 테스트가 레벨 업그레이드라는 관심사를 벗어날 뿐만 아니라 메일 서버에 부담을 줄 수 있다. JavaMail은.. 2023. 4. 4.