81. AOP 사용하기

hanahana·2022년 10월 7일
0

Spring 학원수강

목록 보기
37/45
post-thumbnail

pom.xml에 추가하기

<!-- 	AspectJ Weaver 	AOP를 사용하기 위해서 추가함.-->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>	
<groupId>org.aspectj</groupId>	
<artifactId>aspectjweaver</artifactId>	
<version>${org.aspectj-version}</version>
</dependency>
  • dependency영역에 붙여 넣는다

servlet-context.xml에 추가하기

<!--<beans:beans 태그 안에 -->
<!--xmlns:context="http://www.springframework.org/schema/context" 밑에-->
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="<!--뒤에 주소 추가-->
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
">

<!--맨 아래줄-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

root-context.xml에 추가하기

 <!-- <beans 태그 안에 xmlns:xsi= 밑에-->
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=" <!-- 밑에 추가-->
http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
	
	">

<!-- 아랫줄 beans태그 안에-->
<!-- AOP XML방식 -->
	<bean id="log" class="패키지주소.클래스명"></bean>
	<aop:config>
	<aop:pointcut expression="execution(* 패키지주소..*Impl.*(..))" id="allPointCut"/>
<!-- 해당 패키지 아래 impl로 끝나는 모든 클래스, 모든 메소드 동작 -->
	<aop:aspect ref="log">
		<aop:before method="메소드명" pointcut-ref="allPointCut"/> <!-- 실행전 메소드를 실행한다 -->
		<aop:after method="메소드명" pointcut-ref="allPointCut"/>	<!-- 실행후 메소드를 실행한다 -->
</aop:aspect>
	
	</aop:config>

advice 클래스 만들기

package 클래스 주소;

public class 패키지명 {
	
	public void 실행전메소드() {
		System.out.println("[r공통로그 - LogAdvice] 비지니스 로직 수행 전 동작");
	}

public void 실행후메소드() {
		System.out.println("[공통로그-LogAdvice]  비지니스 로직 수행 후 동작");
	}
}

실행 전,후의 시간체크하기

클래스 만들기

public class AroundLog {

	public Object aorundLogs(ProceedingJoinPoint pp) throws Throwable {
			//ProceedingJoinPoint는 JoinPoint를 상속받아 구현된 인터페이스
			//ProceedingJoinPoint를 사용하는 이유는 advice가 실행되는 시점을
			//프로그래밍 하기 위해서임
			StopWatch stopWatch = new StopWatch();
			//start
			stopWatch.start();
			Object obj = pp.proceed(); //pointcut 적용시점 메소드 proceed라는 메소드를 실행한다(이미 자바안에 들어있는메소드)
			//stop
			stopWatch.stop();
			//메소드가 실행되는 시간 출력
			String methodname = pp.getSignature().getName(); //메소드 이름을 알수있는 코드
			System.out.println(methodname + "()메소드 수행에 걸린 시간 : " +stopWatch.getTotalTimeMillis()+"(ms)");
			
			return obj;
			
		}
}

root-context.xml에 추가하기

<!-- AOP XML방식 -->
	<!--원래 있던 값 주석처리 <bean id="log" class="com.kh.junspring.common.LogAdvice"></bean>-->

	<bean id="aroundLog" class="com.kh.junspring.common.AroundLog"></bean>

	<!--원래 있던 값 주석처리	<aop:config>
		<aop:pointcut
			expression="execution(* 패키지주소..*Impl*.*(..))" id="allPointCut" />
		<aop:aspect ref="log">
			<aop:before method="printLog" pointcut-ref="allPointCut" />
			<aop:after method="printAfterLog" pointcut-ref="allPointCut"/>
		</aop:aspect> -->
		
		<aop:aspect ref="aroundLog">
			<aop:around method="aorundLogs" pointcut-ref="allPointCut"/>
		</aop:aspect>

	</aop:config>
  • 이 부근에서 은근히 헷갈려서 오류가 나왔다. 클래스명과 id명을 틀리지 않도록 주의하자

실행결과

[공통로그 - LogAdvice] 비지니스 로직 수행 전 동작
printOneVyNo()메소드 수행에 걸린 시간 : 17(ms)
[공통로그-LogAdvice] 비지니스 로직 수행 후 동작
[공통로그 - LogAdvice] 비지니스 로직 수행 전 동작
PrintAllReply()메소드 수행에 걸린 시간 : 3(ms)
[공통로그-LogAdvice] 비지니스 로직 수행 후 동작

  • 이런식으로 원하는 정보를 얻을 수 있다.

pointcut에 대해서

<aop:pointcut
			expression="execution(* 패키지 주소..*Impl*.*(..))" id="allPointCut" />
  • 포인트 컷 표현식 ( 패키지주소..Impl.(..))
  • 리턴형 패키지명.클래스명.메소드명(매개변수)로 이루어져있다.
  • * member.model.servicve.*.*(..)
    • 모든 리턴형이며 service패키지에 있는 모든 클래스 및 모든 메소드 (매개변수 0개 이상)
  • * member.model.service..*.*(..)
    • 모든 리턴형, service패키지 및 하위 패키지에 있는 클래스 및 메소드 (매개변수 0개 이상)
  • * member.model.service..*.*()
    • 모든 리턴형, service패키지 및 하위 패키지, 클래스 및 메소드 (매개변수 없음)
  • * member.model.service..*.*(*) : 모든 리턴형 서비스패키지 및 하위패키지의 모든 클래스 및 매소드 (매개변수 1개)
  • * member.model.service..*.*(Integer,..) : 모든 리턴형 서비스패키지 모든 하위패키지 모든하위 클래스 모든 메소드 (매개변수 첫번째 integer를 포함한 그외 매개변수 0개 이상)
  • int member.service..*.*(Integer,..) : 리턴형 int 서비스 패키지의 모든 하위패키지의 모든 클래스, 모든 메소드(매개변수 첫번째 integer를 포함한 그외 매개변수 0개이상)
  • int member.service..*Impl.*(..) : 리턴형 int 서비스패지니의 모든 하위 패키지의 impl이 클래스명 뒤에 있는 모든 클래스의 모든 메소드(매개변수 0개이상)

..은 모든것이라는 의미이다 (*) 매개변수 1개

advice 정의

aop:before - 메소드 실행 전에 적용되는 어드바이스를 정의
aop:around - 메소드 호출 이전, 이후, 예외 발생 등 모든 시점에 적용 가능한 어드바이스를 정의
aop:after- 메소드가 정상적으로 실행되는지 또는 예외를 발생시키는지 여부에 상관없는 어드바이스를 정의
aop:afterreturning- 메소드가 정상적으로 실행된 후에 적용되는
어드바이스를 정의
aop:afterthrowing - 메소드가 예외를 발생시킬 때 적용되는 어드바이스를 정의, try-catch 블록에서 catch 블록과 비슷

profile
hello world

0개의 댓글