Spring

[ Spring ] AOP ( Aspect Oriented Programming ) - 관점 지향 프로그래밍 | 로그 작성하기

dauneee 2022. 4. 4. 14:31

 


사용 목적


공통적으로 수행되는 로직을 공통 로직 ( 횡단 관심 ) 이라 부르는데,

공통 로직과 핵심 로직 ( 비즈니스 메서드, CRUD ) 으로 분리하기 위해 사용한다.


ex) 로깅 인증, 허가, 트랜잭션, 연결, 해제 등등 ( 공통 로직 )

 





1. LogAdvice 클래스를 생성해준다.





2. 비즈니스 메서드마다 new 해줘도 로그는 남겨진다. 하지만 결합도가 높아지기 때문에 유지 보수에 매우 불리한 코드가 된다.





3. 결합도를 낮추기 위해 LogAdvice를 멤버 변수화하여 상단에 작성해준다. (의존관계)





4. 클라이언트에서 실행을 하면 결과는 이렇게 나온다.





Q. 만약에 로그 2를 만들면 어떻게 될까? ( ex. 버전 관리 )


A. 여전히 결합도가 높아서 메서드명을 하나하나 바꾸어줘야 한다.



해결 방법:




1. 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>





2. Namespaces AOP를 추가해준다.






3. applicationContext.xml에서 < bean > 통해 log( ) 수행할 주체( 객체 ) new 해주고, 비즈니스메서드 + log( )( 횡단 관심, 공통 로직 )을 결합해준다.

<?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"
	xmlns:p="http://www.springframework.org/schema/p"
	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.test.app" />
	<bean id="log" class="com.test.app.common.LogAdvice" />
	<aop:config>
		<aop:pointcut
			expression="execution(* com.test.app..*Impl.*(..))" id="aPointcut" />

		<aop:aspect ref="log">
			<aop:before method="printlog" pointcut-ref="aPointcut" />
		</aop:aspect>
	</aop:config>
</beans>





4. 클라이언트에서 실행을 하면 로그 1이 출력된다.


5) 로그 2가 출력되도록 하고 싶다면, applicationContext.xml에서 Bean과 메서드명을 변경해주고 실행하면 된다.

<?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"
	xmlns:p="http://www.springframework.org/schema/p"
	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.test.app" />
	<bean id="log" class="com.test.app.common.LogAdvice2" />
	<aop:config>
		<aop:pointcut
			expression="execution(* com.test.app..*Impl.*(..))" id="aPointcut" />

		<aop:aspect ref="log">
			<aop:before method="printlog2" pointcut-ref="aPointcut" />
		</aop:aspect>
	</aop:config>
</beans>





6. 로그2가 출력되는 모습을 확인할 수 있다.