프로그래밍

[Spring] day66 : AOP(관점 지향 프로그래밍) 본문

자바/Spring

[Spring] day66 : AOP(관점 지향 프로그래밍)

시케 2023. 8. 14. 00:04
728x90
반응형

2023.08.10.목

AOP

AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이다

기존에는 OOP, 즉,객체지향 프로그래밍 방식을 사용하였는데

보다 높은 응집도를 위해 AOP 방식을 사용해보도록 하자

 

현재 로그인 로직은 다음과 같다

1. 로그 출력(객체 확인)

2. 수행할 메서드의 보안 / 인증 / 허가(API) 확인(권한 확인 / 인가 확인)

3. 비즈니스 메서드 실행

4. 관제 로그 작성
※ 컴퓨터가 모든 수행을 기록에 남긴다. 그걸 관제식이라고 하며 관제 로그라고 한다

Controller 메서드

1.(개발자용) 로그

2. 권한 확인 : 보안, 인증, 허가

3. 비즈니스 메서드(CRUD, 핵심 로직, 핵심 관심)

4. 트랜잭션, 보안 관제 로그, ....


비즈니스 메서드가 달라졌는데(사용자의 요청이 달라졌는데)

결론적으로 "진짜" 변경되는곳은 3번밖에 없다 (1,2,4는 계속 사용)

 

관심 분리

"관심 분리(Separation of Concerns)"

관심== 로직

1,2,4: 공통 로직, 횡단 관심(어딜가도 실행 /가로지르는 로직)

3:  핵심 관심, 핵심 로직, 비즈니스 메서드

 

우리는 횡단관심과 핵심관심을 분리하는 관심분리를 할것이다

 

AOP 용어 정리

1. Advice 어드바이스
: 횡단 관심
: 공통 로직
동작 시점을 설정할 수 있다
(비즈니스 메서드 기준으로 전/후/함께/.....)

 

컨트롤러에서 조합하지 않고 서비스레이어에서 진행

 

2. PointCut 포인트컷

: 핵심 관심, 핵심 로직, 비즈니스 메서드. CRUD

공통 로직인 Advice가 결합될 대상

 

 

3. Aspect 애스팩트(Advisor 어드바이저)
: 포인트컷 + 어드바이스
포인트컷과 어드바이스의 "결합" 그 자체를 의미
애스팩트 설정에 따라 위빙이 처리됨

 

4. Weaving 위빙
포인트컷으로 작성한 핵심 관심 메서드가 호출될때
어디바이스에 해당되는 횡단 관심 메서드가 삽입되는 과정 그 자체를 의미
스프링은 런타임 위빙 방식을 사용함

 

5. JointPoint 조인 포인트
: 포인트컷 후보
포인트컷이 될 수 있는 대상들
== 핵심 관심들

 

관심 분리 예제

먼저 pom.xml에 AOP를 위한 의존성을 추가한다

<!-- AOP -->
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
	<version>${org.aspectj-version}</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.8.8</version>
</dependency>

 

applicationContext.xml namespace -> AOP 추가
xmlns:aop="http://www.springframework.org/schema/aop"

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

	<context:component-scan base-package="com.spring.biz" />

</beans>

applicationContext.xml에 추가하는 이유는
Controller의 로직과 소통할 확률이 높기 때문이며
불러내는 시점이 사용자 요청 직후이기 때문이다

또한 AOP 설정 완료되는 시점이
사용자 *.do를 하는 시점보다 더 먼저여야 하기 때문에

루트 컨테이너로 등록된 applicationContext.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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

	<context:component-scan base-package="com.spring.biz" />
	
    <!-- new를 컨테이너가 대신 수행 -->
	<bean id="logAdvice" class="com.spring.biz.common.LogAdvice"></bean>
	<bean id="aroundAdvice" class="com.spring.biz.common.AroundAdvice"></bean>
	
    <!-- AOP 설정 -->
	<aop:config>
    	<!-- execution(OUTPUT FUNCTION(INPUT)) -->
        <!-- *은 하나 .. 은 갯수도 무관 -->
		<aop:pointcut expression="execution(* com.spring.biz..*Impl.*(..))" id="aPointcut"/>
		<aop:pointcut expression="execution(* com.spring.biz..*Impl.select*(..))" id="bPointcut"/>
		
        <!-- logAdvice와 결합 -->
		<aop:aspect ref="logAdvice">
       		<!-- aPointcut 수행"전에" printLog 메서드 호출 -->
			<aop:before method="printLog" pointcut-ref="aPointcut"/>
			<aop:after method="printLogSelect" pointcut-ref="bPointcut"/>
		</aop:aspect>
	</aop:config>
	
	<aop:config>
		<aop:pointcut expression="execution(* com.spring.biz..*Impl.*(..))" id="cPointcut" />
		<aop:pointcut expression="execution(* com.spring.biz..*Impl.select*(..))" id="dPointcut" />
		
		<aop:aspect ref="aroundAdvice">
			<aop:around method="aroundPrintLog" pointcut-ref="dPointcut" />
		</aop:aspect>
	</aop:config>

</beans>

 

XML을 안보면 AOP가 존재하는지도 모른다
장점: 정말 해당 핵심 로직만이 보인다
단점: 설정 확인하려면 XML을 열어 확인해야 한다

서비스를 사용하지 않는 메서드는 로그가 작성되지 않는다
(단순 페이지 이동과 같은 건)
 메서드 호출시 연산 속도가 더 느려지기 때문에 더 가볍고 빠르게 페이지 이동이 가능하다

 

 

https://github.com/jihyean/Spring/tree/main/day66

 

728x90
반응형
Comments