💡 자바 코드로 Spring의 AOP를 흉내낸 것이 프록시 패턴이다.
// 가상의 예외
public class CoronaException extends Exception{
System.out.println("코로나 확진. 자가격리 조치");
}
import java.util.Random;
public class Worker {
public void doSomething() {
// 핵심 관심사항의 전에 Advice
System.out.println("입실체크를 합니다.");
try {
// 핵심 관심사항
System.out.println("소와 같이 일을 합니다.");
if(new Random().nextBoolean()) {
throw new CoronaException();
} else {
// 핵심 관심사항이 정상적으로 실행 완료된 후의 Advice
System.out.println("퇴실체크를 합니다. 6시정시");
}
}
catch(CoronaException e) {
// 핵심 관심사항이 예외 났을 때 Advice
System.out.println("임의 퇴실!!");
}
finally {
// 어쨌든 핵심 관심사항이 끝났을 때 Advice
System.out.println("꿀같은 저녁시간을 보냅니다.");
}
}
}
import java.util.Random;
public class SSAFY {
public void doSomething() {
System.out.println("입실체크를 합니다.");
try {
// 핵심 관심사항
System.out.println("소와 같이 공부를 합니다.");
if(new Random().nextBoolean())
throw new CoronaException();
System.out.println("퇴실체크를 합니다. 6시정시");
}
catch(CoronaException e) {
System.out.println("임의 퇴실!!");
}
finally {
System.out.println("꿀같은 저녁시간을 보냅니다.");
}
}
}
public class Test {
public static void main(String[] args) {
SSAFY ssafy = new SSAFY();
ssafy.doSomething();
}
}
👉 Worker 클래스와 SSAFY 클래스에는 각자의 핵심 관심사항이 존재하면서, 공통 관심사항도 존재한다.
// 가상의 예외
public class CoronaException extends Exception{
System.out.println("코로나 확진. 자가격리 조치");
}
// Person을 인터페이스 타입으로 생성
public interface Person {
public void doSomething();
}
public class Worker implements Person{
@Override
public void doSomething() {
System.out.println("소와 같이 일을 합니다.");
}
}
public class SSAFY implements Person {
@Override
public void doSomething() {
System.out.println("소와 같이 공부를 합니다.");
}
}
import java.util.Random;
public class PersonProxy implements Person {
// ⭐ implements하는 해당 타입의 멤버를 필드로 가지고 있음
private Person person;
public void setPerson(Person person) {
this.person = person;
}
// ⭐ implements한 함수에서 Person 타입 객체의 doSomething( )를 또 호출
// 공통 관심 사항을 프록시 클래스에서 한 번 구현하고
// 핵심 관심 사항은 때마다 들어오는 Person 인터페이스 타입에 따라 결정된다
// 이 때 Person은 인터페이스 타입이기 때문에 Worker, SSAFY 모두 대입 가능
@Override
public void doSomething() {
System.out.println("입실체크를 합니다.");
try {
// 핵심 관심 사항
person.doSomething();
if (new Random().nextBoolean())
throw new CoronaException();
System.out.println("퇴실체크를 합니다. 6시정시");
} catch (CoronaException e) {
System.out.println("임의 퇴실!!");
} finally {
System.out.println("꿀같은 저녁시간을 보냅니다.");
}
}
}
📌📌📌
- 입실, 퇴실, 임의 퇴실, 저녁은 Aspect
- person.doSomething()는 Pointcut
- Worker와 SSAFY는 Target 객체
- Pointcut의 전(입실), 후(퇴실 등)와 같이 위치까지 생각하면 Advice
- 각 객체에 맞게 person.doSomething()이 호출되어 합쳐지는 동작은 Weaving
- 위와 같이 만들어진 완성체를 AOP Proxy
Spring에서는 몇가지 설정들을 통해 AOP가 자동으로 지원된다.
public class Test {
public static void main(String[] args) {
Person ssafy = new SSAFY();
Person worker = new Worker();
// PersonProxy의 객체를 생성해서 호출
PersonProxy pp = new PersonProxy();
pp.setPerson(worker);
pp.doSomething();
}
}