스프링

 AOP ( Aspect Oriented Programming , 관점(관심) 지향적인 프로그래밍 )

- OOP(Object Oriented Programming, 객체지향프로그래밍)를 보완하는 확장적인 개념

- Aspect(측면, 관점, 관심) : 핵심적인 비즈니스 로직은 아니지만 반드시 해야 하는 작업들

- 관심의 분리(Separation of Concerns)를 통해 핵심관점(업무로직) + 횡단관점(트랜잭션,로그,보안,인증 처리 등)으로 관심의 분리를 실현

- 장점 : 중복되는 코드 제거, 효율적인 유지 보수, 높은 생산성, 재활용성 극대화, 변화 수용의 용이성

 

?

 

* AOP의 주요 용어

- Aspect :  공통 관심사(로깅, 보안, 트랜잭션 등)

- Join Points : method를 호출하는 시점, 예외가 발생하는 시점 등과 같이 특정 작업이 실행되는 시점을 의미함

- Advice : Join Points에서 실행되어야 하는 코드(실제로 AOP 기능을 구현한 객체)

- Pointcuts : 실제로 Advice를 적용시킬 대상 method

- Proxy : Advice가 적용되었을 때 만들어지는 객체

 

* Advice의 종류

- Before : target method 호출 전에 적용

- After : target method 호출 후에 적용

- Around : target method 호출 이전과 이후 모두 적용(가장 광범위하게 사용됨)

 

* AOP의 설정 방법

1. pom.xml 에  라이브러리 추가

스프링 4.0 

라이브러리 버전에 따라 실행이 안되는 경우가 있다.

 

첫번째 선택  AOP 라이브러리 버전

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.11</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.8</version>
</dependency>

 

 

두번째 선택  AOP 라이브러리 버전

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.9</version>
</dependency

 

 

세번째 선택 AOP 라이브러리 버전

<dependency>
    <groupId>aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.5.4</version>
</dependency>

<dependency>
    <groupId>aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.5.4</version>
</dependency>

 

스프링의 AOP 를 활용하려면 AOP 관련 라이브러리가 필요하고,

트랜잭션 처리를 위해서 'spring-tx' 라이브러리가 사용돼야 합니다.

	    <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
	
	    <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>

실행이 유무에 안되면 위 라이브러리 추가 또는 제거

설정 내용이 없으면 추가 

 

스프링에서 AOP 를 처리하기 위해서는 Proxy 객체를 생성할 필요가 있습니다.

스프링에서 Proxy 객체를 만드는 방법은 크게 JDK 의 InvocationHandler 를 이용하는 Dynamic Proxy 방식과 CGLIB 를 이용하는 방식이

사용됩니다.

 

2. servlet-context.xml의 Namespace에 aop와 tx 추가

 

root-context.xml 에  AOP의 설정을 통한 자동적인 Proxy 객체 생성을 위해서 아래와 같이 설정을 

한다.

 

	<aop:config></aop:config>	
   <!-- aop의 설정을 통한 자동적인 Proxy 객체 설정 --> 
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	

 

아주 중요

component - scan 파일 위해 설정  또는  상단 위에 설정을 해야 된다.

root-context.xml 에 설정에 해도 안되면 servlet-context.xml 에도 설정을 해라

AOP 마크가 표시 되면 설정이 된 것이다.

 

4. AOP 기능을 지원할 Advice 클래스 작성

 

import java.util.Arrays;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;


//aspectjweaver(1.6.11)와 aspectjrt(1.6.8)  을 mavenrepository 에서 검색해서 pom.xl 넣는다.
//******************* 중요
/*       <!-- aop의 설정을 통한 자동적인 Proxy 객체 설정 --> -->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
        <context:component-scan base-package="com.example.wbe04.*" />
//<aop:config> 추가    - 네임스페이스 aop 체크    
//component 스켄 전에 붙여야 한다.    안되면 root-context.xml 과 servlet-context.xml 양쪽 모두 맨 상단위에 추가
* 
* */
//종단 관심 - 핵심적인 비즈니스 로직
//횡단 관심(Aspect) -공통적인 로직
//Advice - 횡단관심을 모든 코드에서 처리하지 않고 공통적으로 지원할수 있도록
//처리하는 코드 
//@Controller 컨트롤빈
//@Service 서비스빈
//@Repository dao빈
//@Component 기타빈

@Component //스프링에서 관리하는 빈
@Aspect //스프링에서 관리하는 aop bean
public class LogAdvice {
//포인트 컷(실행시점) -Before-실행 전, After -실행 후 , Around -실행 전후
//컨트롤러의 모든 method 실행 전후에 logPrint method 가 호출됨    

//    controller.. 점 두개의미는 controller 다음 모든 패키지 -> xxxController 클래스 의 .* 의미는  모든 메소드 
    @Around(
     "execution(* com.example.wbe04.controller..*Controller.*(..))"
     + " or execution( * com.example.wbe04.service..*Impl.*(..))"
     + " or execution( * com.example.wbe04.model..dao.*Impl.*(..))")
    public Object logPrint(ProceedingJoinPoint joinpoint) throws Throwable{
        
        //시스템의 현재시각
        long startTime =System.currentTimeMillis();
        Object result =joinpoint.proceed();
        
        //클래스 이름 
        String type =joinpoint.getSignature().getDeclaringTypeName();
        //method 이름
        String method=joinpoint.getSignature().getName();
        //매개 변수
        String args =Arrays.toString(joinpoint.getArgs());
        System.out.println("클래스 :"+ type);
        System.out.println("method :"+ method);
        System.out.println("매개변수 :"  + args);
        
        long endTime =System.currentTimeMillis();
        System.out.println("실행시간 : " + (endTime-startTime));
        
        //return joinpoint.proceed();// 컨트롤러의 method가 실행됨 -- 현재는 before로 적용 
        //만약joinpoint.proceed() 중간에 있으면 Around 적용
        System.out.println("=====================구분선========================================");
        return result;
    }
    
}

 

 

 

 

about author

PHRASE

Level 60  머나먼나라

Short accounts make long friends. (셈이 빨라야 친구 사이가 오래간다.)

댓글 ( 4)

댓글 남기기

작성

스프링 목록    more