전체 글

https://github.com/Layton0-0
Spring/이론

[AOP 기반] 프록시 팩토리, 포인트컷, 어드바이스, 어드바이저란?

프록시 팩토리란 무엇일까? 자바 공부와 디자인 패턴을 공부하면서 깨달은 것이 한가지 있다. 공통적으로 사용되는 변수들은 대체적으로 단순하고 직관적이다. @@팩토리 라고 붙은 변수들은 말 그대로 @@를 공장처럼 찍어내는 역할을 한다. 그렇다면 프록시 팩토리는 무슨 역할을 하겠는가? 프록시를 만들어내는 역할을 한다. 프록시 팩토리는 클라이언트로부터 요청이 왔을 때, 인터페이스 기반인 JDK 동적 프록시를 생성할지 클래스 기반인 CGLIB를 호출할 지 선택해 반환해준다. 이 로직이 어떻게 가능한가. JDK 동적 프록시를 생성할 때와 CGLIB를 생성할 때의 이후에 동일한 로직이 호출되게 해주면 된다. 아직 이유는 정확히 모르겠지만 AOP에서는 인터페이스가 있어도 CGLIB를 주로 호출한다고 한다. 이에 대한 ..

Spring/이론

프록시 형태 별 차이 (인터페이스 VS 클래스)

인터페이스 형태가 아닌 클래스 형태에 대해서 프록시를 적용해야할 때가 있을 수 있다. 이럴 때는 어떻게 해야할까? 인터페이스를 implements 하는 것이 아닌 클래스를 extends 해주면 된다. 그 다음은 동일하게 @Override를 해줘서 내부 메소드를 구현해 덮어써주면 된다. 다만 클래스 형태에 프록시를 적용할 때는 신경써줘야 할 점이 있다. 자바 기본 문법에 의해 자식 클래스를 생성할 때는 항상 super()로 부모 클래스의 생성자를 호출해야 한다. 이 부분을 생략하면 기본 생성자가 호출되는데 부모 클래스에서 기본 생성자가 없는 경우 파라미터를 넣어서 super(파라미터) 형식으로 받아야 한다. 프록시는 부모 객체의 기능을 사용하지 않기 때문에 super(null)을 입력하면 되긴 한다. 인터..

Computer Science/Design Pattern

[디자인 패턴] 데코레이터 패턴 (feat. Spring)

전 글에도 언급했다시피 프록시를 사용하는 두가지 GOF 디자인 패턴에는 프록시 패턴과 데코레이터 패턴이 있다. 그 중 데코레이터 패턴은 새로운 기능 추가가 목적인 디자인 패턴이다. 예시 코드에서는 operation이라는 명칭의 메소드로 기능 추가 구현을 했다. 데코레이터 패턴 (기능 추가) 를 적용하기 전에 간결한 예시 코드를 먼저 보자. public interface Component { String operation(); } Component라는 인터페이스를 RealComponent라는 구현체로 구현한다. 그러기 위해서는 RealComponent에서 operation이라는 메소드 내부에 코드를 구현해야한다. 코드로 표현하면 다음과 같다. public class RealComponent implemen..

Computer Science/Design Pattern

[디자인 패턴] 프록시 패턴 (feat. Spring)

프록시는 기존 인터페이스나 클래스를 구현화 / 상속한 메소드나 클래스에 필터를 추가하거나 기능을 추가한다. @Override 와 같은 방법으로. 프록시는 기존 인터페이스와 클래스와 겉모양은 똑같지만 (call 할 수 있는 메소드명이 동일) 안에 로직은 다르다. 분명 프록시를 사용한 목적에 따라 무언가가 더 추가된다. 프록시의 주요 기능은 크게 두가지가 있다. 접근 제어 권한에 따른 접근 차단 캐싱 지연 로딩 부가 기능 추가 원래 서버가 제공하는 기능에 더해서 부가 기능을 수행한다. 예) 요청 값이나, 응답 값을 중간에 변형 예) 실행 시간을 측정해 추가 로그를 남김 접근 제어와 부가 기능 추가이다. 디자인 패턴 중 프록시를 사용하는 방법은 두가지가 있다. 프록시 패턴: 접근 제어가 목적 데코레이터 패턴:..

Computer Science/Design Pattern

[디자인 패턴] 전략 패턴 (feat. Spring)

템플릿 메서드 패턴의 단점을 보완한 전략 패턴이다. 템플릿 메서드 패턴과 추구하는 목표는 동일하다. 변하는 부분과 변하지 않는 부분의 로직을 분리한다. 템플릿 메서드 패턴은 이를 상속으로 구현했다면 전략 패턴은 이를 인터페이스로 구현한다. public interface Strategy { void call(); } 해당 인터페이스를 구현해 변하는 부분을 코드로 구현한다. public class StrategyLogic1 implements Strategy { @Override public void call() { log.info("비즈니스 로직 1 실행"); } } public class ContextV1 { private Strategy strategy; public ContextV1(Strategy ..

Computer Science/Design Pattern

[디자인 패턴] 템플릿 메서드 패턴 (feat. Spring)

템플릿 메서드란? 템플릿 메서드 패턴에 대한 나만의 한줄 요약을 이렇다. 변하는 부분과 변하지 않는 부분을 분리하기 위한 패턴. 변하는 부분을 자유롭게 구현할 수 있도록 추상 클래스 내에 추상 메서드를 만들어 줌으로 써 이를 구현한다. 변하지 않는 부분은 실제 동작할 클래스에 작성한다. 이를 간단히 Spring 내에 구현한 코드로 보면 다음과 같다. public abstract class TemplateMethodPattern() { public void runTemplate() { long startTime = System.currentTimeMillis(); // 변하지 않는 부분 // 비즈니스 로직 실행 (변하는 부분 분리) call(); // 상속받은 메서드 실행 // 비즈니스 로직 종료 long..

Language/Java

[Java] 동시성 문제, 쓰레드 로컬 ThreadLocal

동시성 문제란 무엇일까? 전역 변수에 대한 수정이 여러 쓰레드에서 일어날 경우 값에 대한 변경이나 조회가 예측할 수 없는 방향으로 흘러가는 것을 말한다. 스프링 빈은 기본적으로 싱글톤으로 등록이 된다. 여러 쓰레드에서 하나의 빈에 대해 동시에 접근할 경우에도 동시성 문제가 발생한다. 예를 보자. Thread A에서 어떠한 로직으로 nameStore라는 전역 변수에 userA라는 이름을 저장한다. 이후 바로 Thread B에서 같은 로직으로 nameStore라는 전역 변수에 바로 접근해 userB라는 이름을 저장한다. 이 경우 각 쓰레드가 nameStore라는 전역 변수를 조회하게 되면 어떤 값이 조회될까? 당연히 userB라고 조회가 될 것이다. Thread A는 userA를 예상했지만 userB는 예상..

Spring/이론

[JPA] 응답 값으로 DTO를 전달해야 하는 이유

엔티티를 직접 응답값에 리턴할 경우 엔티티에 보여주기 용 불필요한 로직이 추가된다. 프레젠테이션 계층을 위한 로직이 추가된다. 응답 스펙을 맞추기 위한 로직이 추가된다. @JsonIgnore, 별도의 뷰 로직 등 실무에서는 용도에 따라서 같은 엔티티여도 여러 API에서 이용될 수 있다. 따라서 한 엔티티에 각 API를 위한 프레젠테이션 응답 로직을 전부 담기는 어렵다. 컬렉션을 직접 반환하면 항후 API 스펙을 변경하기 어렵다. 별도로 Result용 클래스 생성으로 해결한다. 상기와 같은 이유로 API 응답 스펙에 맞추어 별도의 DTO를 정의, 반환한다. Result용 클래스 예시 // Result의 사용처 public Result Member() { List collect = memberService...

레이튼
개발 공부 스케치북