spring 13강 AOP의 개요, 로그수집 예제
OOP(Object Oriented Programming, 객체지향프로그래밍)을 보완하는 확장적인 개념
Aspect(측면, 관점, 관심)
핵심적인 비즈니스 로직은 아니지만 반드시 해야하는 작업들
관심의 분리(Separation of Concern)를 통해 핵심Aspect(Business Logic) + 횡단 관점(트랜잭션, 로그, 보안, 인증 처리 등) 으로
Aspect의 분리를 실현
장점 : 중복 코드 제거, 효율적인 유지 보수, 높은 생산성, 재활용성 극대화, 변화 수용의 용이
- Aspect : 공통 관심사(로깅, 보안, 트랜잭션 등)
- Join Points : method를 호출하는 시점, 예외가 발생하는 시점 등과 같이 특정 작업이 실행되는 시점을 의미함
- Advice : Join Points에서 실행되어야 하는 코드 (실제로 AOP 기능을 구현한 객체)
- Before : target method 호출 전에 적용
- After : target method 호출 후에 적용
- Around : target method 호출 이전과 이후 모두 적용 ( 가장 광범위하게 사용됨 )
- Pointcuts : 실제로 Adivce를 적용시킬 대상 method
- Proxy : Advice가 적용되었을 때 만들어지는 객체
AOP 실습 예제 )
사용자가 메시지를 남기면 포인트 10 증가
메시지를 읽으면 포인트 5 증가
.aop : MessageAdvice.java/ LogAdvice.java <<이번 포스팅에서는 로그수입 예제만을 다룸
.controller.message : MessageController.java
.model.message.dto : UserDTO.java / MessageDTO.java
.model.message.dao : MessageDAO/Impl / PointDAO/Impl
.service.message : MessageService/Impl
0. pom.xml에 aspect 관련 라이브러리 추가
1 2 3 4 5 6 | <!-- AspectJ --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${org.aspectj-version}</version> </dependency> | cs |
1. servlet-context의 namespace에서 aop와 tx 체크
해당 문서에서 aop와 tx관련 태그 사용 가능
servlet-context.xml
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> | cs |
2. aop 태그 코드 추가
1 2 | <!-- aop의 설정으로 Proxy 객체를 자동으로 생성 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> | cs |
<aop:aspectj-autoproxy/>
3. AOP기능을 지원할 Adivce 클래스 작성 : LogAdvice.java
로그수집같이 매번 진행해야하지만 부수적인 일들을 Aspect 클래스에서 맡아 처리해준다.
AOP기능을 지원할 클래스 내의 aspect 메서드 상단에 @Around / @Before / @After
@Around는 괄호 안 조건에 해당되는 메서드들의 실행 전, 후에 실행,
@Before는 실행 전,
@After는 실행 후에 Aspect메서드가 실행된다.
1 2 3 | @Around("execution(* com.example.spring02test.controller..*Controller.*(..))" + " or execution(* com.example.spring02test.service..*Impl.*(..))" + " or execution(* com.wxample.spring02test,model..dao.*Impl.*(..))") | cs |
위 어노테이션을 사용하면 해당되는 메서드 옆에 아래와같은 기호가 뜬다.
LogAdvice.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | package com.example.spring02test.aop; import java.util.Arrays; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.springframework.stereotype.Component; @Component //Aspect 클래스는 스프링 bean이어야한다. @Aspect // 공통적인 업무를 지원하는 bean / 스프링에서 지원하는 AOP bean public class LogAdvice { //로깅을 위한 변수 private static final Logger logger = org.slf4j.LoggerFactory.getLogger(LogAdvice.class); //- Around : target method 호출 이전과 이후 모두 적용 ( 가장 광범위하게 사용됨 ) @Around("execution(* com.example.spring02test.controller..*Controller.*(..))" + " or execution(* com.example.spring02test.service..*Impl.*(..))" + " or execution(* com.wxample.spring02test,model..dao.*Impl.*(..))") public Object logPrint(ProceedingJoinPoint joinPoint)throws Throwable { //이 메서드를 호출한 시간 long start = System.currentTimeMillis(); //이 joinPoint.proceed()코드를 기준으로 //이상의 코드가 실행 전 Object result = joinPoint.proceed(); //★핵심업무 실행 //이하의 코드가 핵심업무 실행 후 //호출한 클래스 이름 //컨트롤러인지, 서비스인지, DAO인지 String type = joinPoint.getSignature().getDeclaringTypeName(); String name=""; if(type.indexOf("Controller") > -1) { name =" Controller \t:"; }else if (type.indexOf("Service") > -1) { name = "ServiceImpl \t:"; }else if(type.indexOf("DAO") > -1) { name = "DaoImpl \t:"; } 호출 되는 메서드 이름 logger.info(name+type+"."+joinPoint.getSignature().getName() + "()"); //method에 전달되는 매개변수들 logger.info(Arrays.toString(joinPoint.getArgs())); //이 메서드를 실행이 끝나는 시간 long end = System.currentTimeMillis(); //이 메서드가 호출되고 끝나는데에 걸리는 시간 long time = end - start; logger.info("실행시간 : " + time); return result; } } | cs |
'Spring > study' 카테고리의 다른 글
spring 15강 인터셉터(Interceptor) (0) | 2019.06.28 |
---|---|
spring 14강 AOP와 트랜잭션 처리 실습 (0) | 2019.06.28 |
http와 https의 차이점 (0) | 2019.06.27 |
spring 12강 Google Chart, JFree Chart (0) | 2019.06.26 |
spring 11강 itextpdf를 활용한 pdf 파일 만들기 (0) | 2019.06.26 |