Spring

AOP란? Proxy란?

wintertreey 2024. 7. 8. 17:08

AOP의 핵심기능, 부가기능

 
애플리케이션 로직은 크게 핵심 기능과 부가 기능으로 나눌 수 있다. 

  • 핵심 기능 Core Concerns : 해당 객체가 제공하는 고유의 기능. 
  • 부가 기능 Cross-cutting Concerns : 핵심 기능을 보조하기 위해 제공되는 기능 ( ex: 로그 추적 기능, 트랜잭션 기능 )

보통 기존 프로젝트에 부가 기능을 추가하게 되면, 그림처럼 하나의 클래스가 아닌 여러 클래스에 부가 기능을 추가하게 된다. 예를 들어서 프로젝트의 모든 클래스에 로그 기능을 추가 한다고하면, 하나의 부가 기능(로그 추적)을 여러 곳에 동일하게 사용하게 된다. 
 

AOP란?

Aspect Oriented Programming 관점 지향 프로그램 
 
객체지향의 기본원칙(OOP)으로는 핵심기능에서 부가기능을 분리해서 모듈화하는 것이 매우 어렵다. 
AOP는 부가기능을 애스펙트(Aspect)로 정의하여, 핵심기능에서 부가기능을 분리하여 모듈형태로 만들어준다. 이를 통해 핵심기능을 설계하고 구현할 때 객체지향적인 가치를 지킬수 있도록 도와준다.
 
AOP는 부가 기능을 핵심 기능에서 분리해 한 곳으로 관리하도록 하고, 이 부가 기능을 어디에 적용할지 선택하는 기능을 합한 하나의 모듈. 이름 그대로 애플리케이션을 바라보는 관점을 하나하나의 기능에서 횡단 관심사(cross-cutting concerns) 관점으로 달리 보는 것.
 

AOP 용어 정리 

 

Joinpoint
advice가 적용될 수 있는 위치. Target이 구현한 인터페이스의 모든 메서드는 조인포인트가 될 수 있다.
 
Adivce
joinpoint에  삽입되어 target에게 제공할 부가기능을 담고 있는 코드.
 
Pointcut
여러개의 조인포인트의 결합.
 
Advisor
Advice와 Pointcut을 결합한것. 이것이 곧 Aspect에 해당.
 
Weaving
Advice를 핵심 로직 코드에 삽입함을 말함.
 
Target 
심 로직을 구현하는 클래스
부가기능을 부여할 대상이 된다.
 
Aspect 
여러객체에 공통적으로 적용되는 공통 관점 사항. 
 
Proxy
대상 객체의 래퍼(wrapper) 역할을 한다. Advice를 적용한 대상 객체의 메서드 호출을 가로채고, 필요한 추가 동작을 수행한 후에 대상 객체의 메서드를 호출.

 

Proxy란?

 
프록시는 어드바이스를 타겟 객체에 적용하면서 생성되는 객체이다.
타겟 객체에 대한 호출을 가로챈 다음 어드바이스의 부가기능 로직을 수행하고 난 후에 타겟의
핵심기능 로직을 호출한다.(전처리 어드바이스)
또는 타겟의 핵심기능 로직 메서드를 호출한 후에 부가기능(어드바이스)을 수행하는 경우도 있다.(후처리 어드바이스)
 
Proxy는 유저 클라이언트와 서버 사이에 중개장비로서 캐시 기법을 사용하여 서버로 가는 트래픽을 감소시킨다. 서버에 몰리는 유저가 많을 수록 서버의 트래픽이 증가하여 접속 시간이 지연되거나 서버 자체가 다운되는 경우가 있다. 서버가 Proxy를 가지게 되면 클라이언트는 Proxy에 접속하고 Proxy가 서버에 한번 접속하여 그 내용을 읽어들여 저장하고 클라이언트에 제공하게 되므로 서버에 가는 트래픽이 감소하게 된다. 서버는 Proxy를 많이 둘 수록 원활하게 동작한다. 클라이언트가 Proxy를 이용하여 서버에 접속하게 되면 서버에는 클라이언트에 대한 정보가 기록된다. 하지만 Anonymous Proxy를 이용하면 Anonymous Proxy의 주소가 기록되므로 클라이언트의 정보가 기록되지 않는다.

++ 정보처리기사 실기 내용 추가
디자인패턴> 구조패턴> Proxy

다수의 객체로 생성될 경우 모두가 갖는 본질적인 요소를 클래스 화하여 공유함으로써 메모리를 절약하고, '클래스의 경량화'를 목적으로 하는 디자인 패턴.

여러 개의 '가상 인스턴스'를 제공하여 메모리 절감.
 
 


실습

작업을 위해 pom.xml에 aspectj의 maven dependency를 추가해준다. 
 
https://central.sonatype.com/artifact/aspectj/aspectjweaver

Maven Central: aspectj:aspectjweaver

Discover aspectjweaver in the aspectj namespace. Explore metadata, contributors, the Maven POM file, and more.

central.sonatype.com

 
 
메인 로직을 먼저 구현한다.
 
MessaageInter.java

package pack;

public interface MessageInter {
	void sayHi(); //AOP가 적용될 메소드: 일반적으로 인터페이스에서 선언
	//...
}

 
void sayHi()가 aop가 적용될 메소드, 즉 joinpoint. 
 
MessageImpl.java

package pack;

public class MessageImpl implements MessageInter{
	// 핵심 로직 클래스: target
	
	private String name;
	
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public void sayHi() {
		System.out.println("안녕 "+name+ "님! BusinessLogic 수행" );
		// 현재 메소드 처리시간이 길다고 가정하고 인위적으로 지연시간부여
		int t=0;
		while(t<5) {
			try {
				Thread.sleep(1000);
				System.out.println("🎶");
				t++;
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		System.out.println("sayHi 처리완료😎😎");
		
	}

}

 
이 클래스가 핵심로직클래스 즉 target이다.
 
자 그럼 cross-cutting 할 Aspect 클래스를 살펴보자.

package aspect;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

//핵심 로직에 삽입할 관심 코드: ex) transaction, login, security, log..
public class MyAdvice implements MethodInterceptor{
	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		// joinpoint에 삽입될 동작할 코드 기술
		
		System.out.println("핵심로직수행 전 😶‍🌫️블라블라😶‍🌫️처리");
		//target 메소드 이름 얻기
		String tmname= invocation.getMethod().getName();
		System.out.println("적용된 메소드명: "+tmname);
		
		Object object = invocation.proceed(); //선택된 핵심로직 메소드 중 하나 - sayHi()
		
		System.out.println("핵심로직수행 후 😊마무리처리");
		
		return object;
	}
}

 
aopinit.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
	
	<!-- Target -->
	<bean id="targetBean" class="pack.MessageImpl">
		<property name="name" value="스프링" />
	</bean>
	
	<!-- Advice(Aspect): target으로 weaving -->
	<bean id="myAdvice" class="aspect.MyAdvice"/>
	
	<!-- proxy -->
	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target">
			<ref bean="targetBean" />
		</property>
		<property name="interceptorNames">
			<list>
				<value>hiAdvisor</value> <!-- 작성한 Advisor를 줌 -->
			</list>
		</property>
	</bean>
	
	<!-- Advisor(Advice+pointcut) -->
	<bean id="hiAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advice">
			<ref bean="myAdvice"/>
		</property>
		<property name="pointcut">
			<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
				<property name="pattern">
					<value>.*sayHi*.</value>
				</property>
			</bean>
		</property>
	</bean>
	
</beans>

 
출력할 Main.java

package pack;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("aopinit.xml");

		//AOP 적용 전 
//		MessageInter inter = (MessageInter)context.getBean("targetBean");
//		inter.sayHi();
		
		//AOP 적용 후
		MessageInter inter = (MessageInter)context.getBean("proxy");
		inter.sayHi();
		
	}

}

 
 
콘솔 출력결과를 통해  AOP가 작동되는 과정과
target <--------------------    apsect 을위해
     joinpoint   proxy   adivce 
용어들도 파악할 수 있다. 


 
https://shlee0882.tistory.com/206

Spring AOP, Aspect 개념 특징, AOP 용어 정리

1. Spring AOP의 핵심기능과 부가기능 - 업무 로직을 포함하는 기능을 핵심 기능(Core Concerns)- 핵심 기능을 도와주는 부가적인 기능(로깅, 보안)을 부가기능(Cross-cutting Concerns) 이라고 부른다. 2. AOP란?

shlee0882.tistory.com

 
https://hstory0208.tistory.com/entry/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-AOPAspect-Oriented-Programming%EB%9E%80-Aspect

[Spring] 스프링 AOP(Aspect Oriented Programming)란? - @Aspect

AOP를 사용하지 않는다면 ? AOP에 대해 설명하기 전에 AOP를 사용하는 이유에 대해 먼저 알아 봅시다. 애플리케이션 로직은 크게 핵심 기능과 부가 기능으로 나눌 수 있습니다. 핵심 기능 : 해당 객

hstory0208.tistory.com

 
https://blog.naver.com/comma_dev/223504921354

[Spring] AOP

Proxy 프록시란(Proxy)란 클라이언트가 사용하려는 대상인 것처럼 행동해서 클라이언트의 요청을 받아 실...

blog.naver.com

 
https://cafe.daum.net/flowlife/HrhB/19
https://cafe.daum.net/flowlife/HrhB/38