프록시 패턴

호떡·2022년 10월 12일
0

💡 자바 코드로 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();
	}
}

0개의 댓글