일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- aop
- 기계학습
- 스프링부트 에러
- 지도학습
- Proxy 패턴
- 스프링
- 스프링 프레임워크
- 백기선 강좌
- Do It 정직하게 코딩하며 배우는 딥러닝 입문
- 노션
- 딥러닝
- PSA
- 노드
- 강화학습
- krpano
- 강좌 정리
- 비지도학습
- @Autowired
- Dependency Injection
- jetbrains
- 노션 Formula
- express
- syncronized
- IoC 컨테이너
- 의존성주입
- timezone error
- database error
- 스프링 빈
- express-generator
- 프레임워크
- Today
- Total
hyungmuk's blog
스프링 입문강좌 정리 - AOP 본문
IoC, AOP, PSA를 스프링 트라이앵글이라고 한다.
그중에 IoC는 저번 시간에 했고, 이번 시간에는 AOP에 대해서 알아본다.
AOP의 사전적 의미
Aspect Oriented Programing : 관점 지향적인 프로그래밍
AOP를 구현하는 방법은 3가지가 있다.
-
컴파일을 이용하는 방법
A.java가 A.class로 컴파일 될 때 AspectJ를 이용하여 AOP를 구현한다.
-
바이트코드를 조작하는 방법:
컴파일된 A.class가 메모리에 올라갈 때 AspectJ를 이용하여 AOP를 구현한다.
-
프록시 패턴을 이용한 방법
이 방법이 스프링에서 사용되는 AOP 방법이다.
프록시(Proxy)에 대해서는 프록시 패턴을 설명하고 있는 글
https://refactoring.guru/design-patterns/proxy
프록시 패턴
강좌에서 프록시패턴에 대해 코드로 보여주고 자세하게 설명은 해주시지 않아서 느낌만 아는 정도라 한 블로그에서 다음 글을 가지고 왔다.
Proxy는 우리말로 대리자, 대변인이라는 뜻입니다. 대리자, 대변인은 다른 누군가를 대신해서 그 역할을 수행하는 존재입니다. 프로그램에서 봤을 때도 똑같습니다. 프록시에게 어떤 일을 대신 시키는 것입니다.
구체적으로 인터페이스를 사용하고 실행시킬 클래스에 대한 객체가 들어갈 자리에 대리자 객체를 대신 투입해 클라이언트 쪽에서 실제 실행시킬 클래스에 대한 객체를 통해 메서드를 호출하고 반환 값을 받는지, 대리자 객체를 통해 메서드를 호출하고 반환 값을 받는지 전혀 모르게 처리하는 것입니다.
일종의 프록시는 비서 역할을 하는 것 같네요. 중요한 것은 흐름 제어만 할 뿐 결괏값을 조작하거나 변경시키면 안 됩니다. 제가 비서에게 대신 연락처 목록을 정리해서 달라고 지시했다면, 그 연락처 목록을 정리한 결과만 컴퓨터에서 받아서 전달해 줘야 연락처를 수정하거나, 전화를 하면 안 되겠죠? 마찬가지로 프록시도 자신의 의견을 반영하는 것을 목적으로 하지 않고 제어의 흐름을 변경하거나 다른 로직을 수행하기 위해 사용하는 것입니다.
하나 더 추가적으로 Proxy 패턴에 특징을 알아봅시다.
- 대리자는 실제 서비스와 같은 이름의 메서드를 구현한다. 이때 인터페이스를 사용한다.
- 대리자는 실제 서비스에 대한 참조 변수를 갖는다(합성)
- 대리자는 실제 서비스의 같은 이름을 가진 메서드를 호출하고 그 값을 클라이언트에게 돌려준다.
- 대리자는 실제 서비스의 메서드 호출 전후에도 별도의 로직을 수행할 수도 있다.
출처 : Limky 삽질블로그, https://limkydev.tistory.com/79
예제 소스코드
// Payment.java
package org.springframework.samples.petclinic.proxy;
public interface Payment {
void pay(int amount);
}
// Cash.java
package org.springframework.samples.petclinic.proxy;
public class Cash implements Payment {
@Override
public void pay(int amount) {
System.out.println(amount + " 현금 결제");
}
}
// CreditCard
package org.springframework.samples.petclinic.proxy;
public CreditCard implements Payment {
Payment cash = new Cash();
@Override
public void pay(int amount) {
if(amount > 100) {
System.out.println(amount + " 신용카드");
} else {
cash.pay(amount);
}
}
}
Cash.java 수정하지 않고 pay 메소드 앞뒤로 코드를 추가하려 한다면
CreditCard.java 처럼 pay를 구현할 때 Cash의 pay메소드를 실행하는 것의 앞뒤로 코드를 추가해 주면 된다.
예제 소스코드 2
pay 메소드 수행시간을 측정하는 예제
// Cash.java
package org.springframework.samples.petclinic.proxy;
public class Cash implements Payment {
@Override
public void pay(int amount) {
System.out.println(amount + " 현금 결제");
}
}
// CashPerf.java
package org.springframework.samples.petclinic.proxy;
import org.springframework.util.StopWatch;
public class CashPerf implements Payment {
Payment cash = new Cash();
@Override
public void pay(int amount) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
cash.pay(amount);
stopWatch.stop();
System.out.println(stopWatch.prettyPrint());
}
}
// Store.java
package org.springframework.samples.petclinic.proxy;
public class Store {
Payment payment;
public Store(Payment payment) {
this.payment = payment;
}
public void buySometing(int amount) {
payment.pay(amount);
}
}
메서드의 성능을 측정할 때도 위와 같이 Proxy 패턴을 사용하면 된다.
※ @Transactional 어노테이션도 위와 같은 원리로 jdbc 코드에 앞뒤로 코드를 붙여준다.
https://www.youtube.com/watch?v=MorRFegeFqA&list=PLfI752FpVCS8_5t29DWnsrL9NudvKDAKY&index=10
'개발 & 공부 > 스프링' 카테고리의 다른 글
스프링 입문강좌 정리 - PSA (0) | 2020.03.28 |
---|---|
스프링 입문강좌 정리 - AOP 애노테이션 (0) | 2020.03.27 |
스프링 입문 강좌 정리 - 의존성 주입(Dependency Injection) (0) | 2020.03.20 |
스프링 입문 강좌 정리 - 빈 (Bean) (0) | 2020.03.19 |
스프링 입문 강좌 정리 - IoC 컨테이너 (0) | 2020.03.19 |