본문 바로가기
STUDY/SPRING

스프링(3.0) Spring AOP

by Anne of Green Galbes 2019. 4. 17.

Spring AOP



스프링 AOP(Aspect Oriented Programming : 관점지향프로그래밍)


패키지에 상관 없이 내가 필요로하는 부분을 찾는게 가능

○ 불특정 다수의 객체(클래스,메소드)에 코드를 탈출할 수 있게 만드는 기능

○ 공통적으로 사용되는 부분(공통화해서 라이브러리 할 수 있는 부분 : 트랜잭션 혹은 예외부분)을 별도로 분리하는 기술

○ 공통된 기능을 재사용하는 기법


1. 용어

① 횡단 관심사

○ 모든 영역에 공통적으로 적용되는 코딩

○ 중간중간 삽입되어야 할 기능들 ( 로깅,보안,트랜잭션..)

○ 주로 메소드 단위로 확인

② 조인 포인트

○ 어드바이스를 실행할 수 있는 지점 → 포인트컷의 후보

○ 어플리케이션 실행의 특정 지점


③ 어드바이스

○ 조인포인트에게 실행 할 것인가?

○ 종류

- before : 메서드 호출 전

- after : 메서드 호출 후

- after returning : 메서드가 정상적으로 실행된 후

- after throwing : 메소드를 실행하는 도중 에러가 발생하는 경우

  - around : 메소드 앞 뒤로 실행

 ○ 조인포인트에서 실행 할 코드


④ 포인트컷

○ 어드바이스를 실행하는 조인 포인트

○ 어드바이스를 실행하는 시간(위치)


⑤ 애스팩트

○ 어드바이스 + 포인트컷

 ○ 무엇을 언제할지 정의


1. 프로젝트 생성

new > Legacy Project >


2. AOP 라이브러리 다운

① Spring AOP

<!-- spring-aop -->

<dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-aop</artifactId>

   <version>${spring.framework.version}</version>

</dependency>


② AspectJ Runtime

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->

<dependency>

  <groupId>org.aspectj</groupId>

  <artifactId>aspectjrt</artifactId>

  <version>1.5.4</version>

</dependency>


③ AspectJ Weaver

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->

<dependency>

  <groupId>org.aspectj</groupId>

  <artifactId>aspectjweaver</artifactId>

  <version>1.8.0</version>

</dependency>


④ CGLIB

<!--cglib -->

<dependency>

  <groupId>cglib</groupId>

  <artifactId>cglib</artifactId>

  <version>3.2.4</version>

</dependency>


⑤ 라이브러리 파일 확인


3. 클래스 작성

○ 위치 : com/main/java > com.exe.aop

① targetA.java

② targetB.java


3-1. 실행할 시점에 따라 클래스 파일 생성

① MyBeforeAdvice.java

○ after, afterReturning, afterThrowing도 동일 코딩

package com.exe.aop;


public class MyBeforeAdvice {

public void beforeMethodCall() {

System.out.println("Jointpoint 메소드가 실행되기 전에...");

}

}


② MyAroundAdvice.java

○ processed();

- Around 어드바이스에서는 processed()를 만나기 전 까지는 Before 어드바이스와 같은 상태

- 이를 기준으로 위는 before, 밑은 after throwing

package com.exe.aop;

import org.aspectj.lang.ProceedingJoinPoint;


public class MyAroundAdvice {

public Object aroundMethodCall(ProceedingJoinPoint jointPoint) {

Object  result = null;

try {

System.out.println("Joinpoint 메소드 실행 전..(Around)");

result = jointPoint.proceed();

System.out.println("Joinpoint 메소드 실행 후..(Around)");

} catch (Throwable e) {

}

return result;

}

}


4. app-context.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

https://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

https://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/aop

https://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<description>Example configuration to get you started.</description>

<context:component-scan base-package="com.exe.aop" />

</beans>


② aspect 작성

expression="execution(public void com..aop.*.*(..))"

 - excution(메소드 접근지정자 반환값 패키지이름.클래스이름.메소드이름(매개변수)

 - ..은 생략 → 사이에 뭐가 오든 상관 없다

 - com..aop : 맨 앞은 com, 맨 뒤는 aop, 중간은 상관 없음

<!-- 객체 생성 -->

<bean id="beforeAdvice" class="com.exe.aop.MyBeforeAdvice"/>

<aop:config>

            <!-- ref : aspect를 적용할 객체 -->

<aop:aspect ref="beforeAdvice">

<!-- 실행할 행동 -->

<aop:pointcut id="beforePointcut"

expression="execution(public void com..aop.*.*(..))"/>

<!-- 실행할 시점 -->

<!-- method :  -->

<!-- aop:pointcut의 id와 ref는 같아야 한다 -->

<aop:before method="beforeMethodCall" pointcut-ref="beforePointcut"/>

</aop:aspect>

</aop:config>


5. main작성

package com.exe.aop;

import org.springframework.context.support.GenericXmlApplicationContext;

public class AopMain {

public static void main(String[] args) {

GenericXmlApplicationContext context = new GenericXmlApplicationContext("app-context.xml");

TargetA ta = (TargetA)context.getBean("targetA");

ta.doAnother1();

ta.doAnother2();

ta.doSomething1();

ta.doSomething2();

TargetB tb = (TargetB)context.getBean("targetB");

tb.doAnother1();

tb.doAnother2();

tb.doSomething1();

tb.doSomething2();

}

}



6. 어노테이션으로 변경

① app-content.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

https://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

https://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/aop

https://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

<description>Example configuration to get you started.</description>

<context:component-scan base-package="com.exe.aop" />

<!-- aop를 어노테이션으로 만들겠다 -->

<aop:aspectj-autoproxy/>

</beans>


② 클래스 변경

MyBeforeAdvice.java

 - @Aspect : 객체를 IoT까지 실행

        <aop:aspect ref="beforeAdvice"> </aop:aspect>

 - @Component : bean객체 생성

                             <bean id="beforeAdvice" class="com.exe.aop.MyBeforeAdvice"/>

package com.exe.aop;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;


@Aspect

@Component

public class MyBeforeAdvice {

//실행시점 및 적용할 메소드 지정

@Before("execution(* com..aop.*.*(..))")

public void beforeMethodCall() {

System.out.println("Jointpoint 메소드가 실행되기 전에...");

}

}

'STUDY > SPRING' 카테고리의 다른 글

스프링(3.0) 게시판 스프링 JDBC로 변경  (0) 2019.04.18
스프링(3.0) MVC : 게시판 만들기  (0) 2019.04.18
스프링(3.0) MyBatis 연결  (0) 2019.04.17
스프링(3.0) Spring JDBC  (0) 2019.04.16
스프링(3.0) Java에서 DB사용  (0) 2019.04.16

댓글