Spring Framework & MyBatis
스프링 프레임워크 & 마이바티스 강의
탑크리에듀 교육센터
CONTENTS
3. Spring AOP((Spring Aspect Oriented Programming)
3.1 AOP 개요
3.2 AOP HelloWorld
3.2.1 AOP HelloWorld(프로그래밍을 통한 AOP 구현)
3.2.2 AOP HelloWorld(XML Schema Based AOP 구현)
3.2.3 HelloWorld(@AspectJ Annotation Based AOP 구현)
3.2.4 생성자 주입(Constructor Injection) – 어노테이션 기반
3.3 AOP 충고(Advice)
3.4 프로그래밍적인 방법을 통한 AOP 구현
(ProxyFactory 이용)
Chapter 3
Spring AOP((Spring Aspect Oriented Programming)
~ 3.4
3. Spring AOP((Spring Aspect Oriented Programming)
3-1. AOP 개요
 IoC를 이용하여 협력하는 객체를 쉽게 연결 가능지만 때로는 전체 애플리케이션에 걸쳐 사용되어야 하
는 공통적인 기능(횡단관심사)이 필요할 수도 있다.
 DI의 목적이 Application간 결합 도를 떨어뜨리는 것이 목표라면 AOP의 목적은 횡단관심사(Cross-
Cutting Concerns, 예외처리, 로깅, 인증, 보안, 트랜잭션)와 이에 영향을 받는 객체간에 결합도를 떨어뜨
리는 것이다. 즉 AOP는 횡단관심사를 모듈화하는 프로그래밍 기법으로 공통적인 기능을 Aspect라 불리
는 한곳에서 정의한다.
 새로운 기능을 적용하려고 하는 클래스를 수정할 필요 없이 그런 기능을 어디에 어떻게 적용할 것인지
선언적 또는 어노테이션으로 정의가 가능하다.
 각 횡단관심사에 관한 로직이 애플리케이션 전체에 걸쳐 관리되지 않고 Aspect라고 하는 곳에서 관리되
고 어플리케이션은 고유의 비즈니스 로직 처리에 충실할 수 있다.
 Logging은 시스템 내에서 거의 모든 경우에 적용하긴 하지만 특정한 비즈니스 로직과는 전혀 관련이 없
다. 만일 AOP방식으로 구현한다면 실제 비즈니즈 로직의 구현을 담당하는 객체는 아무런 로그 관련 객
체 정보가 없고 이 객체의 특정 메소드를 호출하는 시점에 지정된 다른 서비스(로깅)가 실행된다.
 횡단 관심사(Cross-Cuitting Concern) : 여러 개의 모듈에 걸치는 시스템 전체적인 부가적인 요구사항을
다룬다. 대표적인 횡단 관심사의 일부 예들 든다면 인증, 로깅,트랜잭션 무결 성, 오류검사, 정책시행
 핵심 관심사(Primary Concern) : 각 모듈에서 수행해야 하는 기본적이고 대표적인 업무처리 기능
3. Spring AOP((Spring Aspect Oriented Programming)
3-1. AOP 개요
 Springdptj AOP 구현 방법
 소스코드에서 직접 AOP 구현 : Proxy Factory 기반 AOP
 선언적 AOP 설정 메커니즘
Proxy Factory Bean 사용 : 스프링 Application Context를 XML에 선언적으로 선언하여 빈 정의를 기반으로
AOP 프록시 생성한다.
Spring aop 네임스페이스 : aop 네임스페이스를 이용하여 Aspect 및 DI 요구사항을 간단히 정의. Aop 네임
스페이스도 내부적으로 Proxy Factory Bean 사용한다.
@Apect J Annotation : @AspectJ방식의 어노테이션을 사용하여 클래스 내에서 AOP 설정이 가능하다, 이
방식은 AspectJ를 기반으로 하고 있으며 AspectJ 라이브러리가 필요하다. 이 역시 스프링에서는 프록시
메커니즘을 이용하는데 Application Context를 부트스트랩 할 때 타깃에 대해 프록시를 생성한다.
Spring AOP는 메소드 가로채기로 제한, 만약 그 이상의 기능
(생성자 또는 멤버변수에 대한 가로채기)을 필요로 하는 경우 Proxy 기반 AOP
대신 AspectJ를 이용해서 Aspect를 구현해야 한다.
3. Spring AOP((Spring Aspect Oriented Programming)
 스프링의 충고(Advice)는 자바로 작성 : Pointcut의 경우 Advice를 어디에 적용할지를 정의하는 데 XML
설정 파일, AspectJ Expression으로 정의한다. AspectJ는 자바언어를 확장한 형태로 구현. 새로운 도구와
문법을 배워야 한다.
 스프링의 Aspect는 실행시간에 만들어진다. 빈을 감싸는 Proxy 객체를 실행시간에 생성하므로 Aspect가
Spring 관련 빈에 위빙(Weaving)된다. Proxy 객체는 타겟 객체로 위장해서 메소드 호출을 가로채고, 타
겟 객체로 호출을 전달한다. 어플리케이션이 실제 Proxy 객체를 필요로 할 때까지 target를 생성하지 않
으므로 즉 Proxy가 실시간으로 생성되므로 Aspect를 위빙 하기 위해 별도 컴파일러가 필요 없다.
 스프링은 AOP연맹의 인터페이스를 구현하며 메소드 호출 결합점(Join Point)만 제공한다.
3. Spring AOP((Spring Aspect Oriented Programming)
 충고AOP 용어
3. Spring AOP((Spring Aspect Oriented Programming)
 충고AOP 용어
3. Spring AOP((Spring Aspect Oriented Programming)
 스프링에서 Proxy 객체를 생성하는 방법은 2가지.
1. 대상 객체가 특정 메소드를 공개하는 인터페이스를 구현한다면 JDK의 java.lang.reflect.Proxy 클래스를 이용하며 이 클
래스는 필요한 인터페이스를 구현한 새로운 Proxy 객체를 동적으로 생성할 수 있으며 target 객체의 인터페이스를 통한
호출은 모두 가로채서 Advice를 수행한다.
2. 대상 클래스가 어떤 인터페이스를 구현하고 있지 않다면 CGLIB이라는 라이브러리를 이용하여 대상클래스의 서브클래
스를 생성 시킨다. 이 서브클래스를 생성시킴으로써 스프링은 충고를 엮을 수 있으며 서브클래스에 대한 호출을 대상 클
래스에 위임 할 수 있다. 이 경우 final 메소드는 충고를 받을 수 없으며(final Method는 대상클래스의 서브클래스를 생성
해서 메소드를 재정의 해야 하는데 final인 경우 곤란함) 애플리케이션이 좀 더 느슨하게 결합되게 하기 위해 이 방법보단
인터페이스를 통해 프록시를 만드는 것이 선호된다.
 스프링 어스팩트 : 스프링 AOP에서 애스팩트는 Advisor 인터페이스를 구현한 클래스의 인스턴스로 표
시하는데 Advisor를 구현한 몇 개의 클래스를 제공한다. Advisor의 하위 인터페이스로는
IntroductionAdvisor, PointcutAdvisor등이 있는데 PointcutAdvisor 인터페이스는 포인트컷을 사용하여
조인포인트에 어드바이스를 적용하는 모든 Advisor가 구현한다.
3. Spring AOP((Spring Aspect Oriented Programming)
 File -> New -> Spring Legacy Project -> Simple Spring Maven 선택 후 프로젝트 명을 “aophello1” 이
라고 입력 후 “Finish” 클릭
 단순히 "Hello AOP..." 이라고 출력하는 PrintMsg 클래스의 메소드 sayHello()가 있고 이 클래스에 주변
충고(어라운드 어드바이스, Around Advice)를 추가해 sayHello() 메소드 실행 전/후 필요한 기능
("메소드 실행 전 안녕...", "메소드 실행 후 안녕...")을 출력하고자 한다.
3-2. AOP HelloWorld
3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)
 [IprintMsg.java]
package aophello1;
public interface IPrintMsg {
public void
sayHello();
}
 [PrintMsg.java]
타겟 클래스(충고가 적용될 클래스, 횡단관심사
기능을 구햔한 클래스
본 예제에서는 간단히 로깅만 하기로 한다.
package aophello1;
public class PrintMsg implements IPrintMsg {
public void sayHello() {
System.out.println("Hello AOP...");
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)
 [MyAroundAdvice.java]
어라운드 어드바이스(AroundAdvice)의 구현체, 충고 MethodInterceptor는 메소드 호출용 어라운드 어드바이스의 표준 인터페이스이다.
MethodInvocation은 어드바이스를 추가하기 위한 메소드 호출을 나타내며 이 객체를 사용하면 메소드 호출이 실행되는 시점
(메소드 실행 전/후)을 제어할 수 있다.
package aophello1;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation)
throws Throwable {
System.out.println("메소드 실행전 안녕...");
Object ret = invocation.proceed();
System.out.println("메소드 실행후 안녕...");
return ret;
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)
 [HelloMain.java]
Proxt 빈 객체를 생성후 MyAroundAdvice 및 타겟 객체인 PrintMsg를 위빙하여 프록시 생성
package aophello1;
import org.springframework.aop.framework.ProxyFactory;
public class HelloMain {
public static void main(String[] args) {
IPrintMsg target = new PrintMsg();
//Proxy 빈껍데기 생성
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new MyAroundAdvice()); //충고 add
pf.setTarget(target); //타겟 add
PrintMsg proxy = (PrintMsg)pf.getProxy();
proxy.sayHello();
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)
 [HelloMain.java]
Proxt 빈 객체를 생성후 MyAroundAdvice 및 타겟 객체인 PrintMsg를 위빙하여 프록시 생성
package aophello1;
import org.springframework.aop.framework.ProxyFactory;
public class HelloMain {
public static void main(String[] args) {
IPrintMsg target = new PrintMsg();
//Proxy 빈껍데기 생성
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new MyAroundAdvice()); //충고 add
pf.setTarget(target); //타겟 add
PrintMsg proxy = (PrintMsg)pf.getProxy();
proxy.sayHello();
}
}
 [실행결과]
메소드 실행 전 안녕...
Hello AOP...
메소드 실행 후 안녕...
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)
 File -> New -> Spring Legacy Project -> Simple Spring Maven 선택 후 프로젝트 명을 “aophello1” 이
라고 입력 후 “Finish” 클릭
 스프링에서 제공하는 aop Namespace를 이용하는 방법으로 타깃 클래스의 sayHello1(), sayHello2() 메
소드 중 sayHello1() 메소드만 주변충고가 적용되도록 구성한 예제이다.
 [pom.xml]에 AOP를 위한 라이브러리 추가
<!-- Spring AOP + AspectJ -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-
framework.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)
 [IprintMsg.java]
package aophello1;
public interface IPrintMsg {
public void sayHello1();
public void sayHello2();
}
 [PrintMsg.java]
package aophello1;
public class PrintMsg implements IPrintMsg {
public void sayHello1() {
System.out.println("Hello AOP1...");
}
public void sayHello2() {
System.out.println("Hello AOP2...");
}
}
 [LogginAspect.java]
// XML Schema Based AOP 구현에서는 Aspect클래스에 충고용 메소드를 정의한다.
// 아래 myAdvice가 주변충고용 메소드로 어떤 메소드에 이 충고가 내려갈지는 XML에서 설정을 한다.
// pjp.procees() 메소드를 통해 원래 타겟클래스의 sayHello1() 메소드가 호출된다.
package aophello1;
import org.aspectj.lang.ProceedingJoinPoint;
public class LoggingAspect {
public void myAdvice(ProceedingJoinPoint pjp)
throws Throwable{
System.out.println("메소드 실행전 안녕..."); //메소드 실행 전
Object ret = pjp.proceed();
System.out.println("메소드 실행후 안녕..."); //메소드 실행 후
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)
 [Src/main/resources/aophello1.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd ">
<aop:config>
<aop:aspect id="helloAspect" ref="logging"> <!-- ref에는 충고를 담고있는 Aspect가 온다 
<aop:pointcut id="selectSayHello1"
expression="execution(* aophello1.PrintMsg.sayHello1(..))"/>
<!—myAdvice는 Aspect 클래스(logging)의 충고용 메소드-->
<aop:around pointcut-ref="selectSayHello1" method="myAdvice"/>
</aop:aspect>
</aop:config>
<!-- Definition for printMsg bean, 타겟클래스 -->
<bean id="printMsg" class="aophello1.PrintMsg" />
<!-- Definition for logging aspect 충고들이 오여있는 Aspect클래스-->
<bean id="logging" class="aophello1.LoggingAspect"/>
</beans>
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)
 [HelloMain.java]
package aophello1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("aophello1.xml");
IPrintMsg printMsg = (IPrintMsg) ctx.getBean("printMsg");
//sayHello1만 충고가 내려가도록 되어 있다.
printMsg.sayHello1();
printMsg.sayHello2();
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)
 File -> New -> Spring Legacy Project -> Simple Spring Maven 선택 후 프로젝트 명을 “aophello1” 이라고
입력 후 “Finish” 클릭
 스프링에서 제공하는 aop Namespace를 이용하는 방법으로 타깃 클래스의 sayHello1(), sayHello2() 메소드
중 sayHello1() 메소드만 주변충고가 적용되도록 구성한 예제이다.
 [pom.xml]에 AOP를 위한 라이브러리 추가
<!-- Spring AOP + AspectJ -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-framework.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)
 [IprintMsg.java]
package aophello1;
public interface IPrintMsg {
public void sayHello1();
public void sayHello2();
}
 [PrintMsg.java]
package aophello1;
public class PrintMsg implements IPrintMsg {
public void sayHello1() {
System.out.println("Hello AOP1...");
}
public void sayHello2() {
System.out.println("Hello AOP2...");
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)
 [LogginAspect.java]
// Aspect클래스로 충고용 메소드 및 포인트컷을 정의한다.
// 아래 myAdvice가 주변충고용 메소드로 메소드 상단에 포인트컷을 정의했다.
// pjp.procees() 메소드를 통해 원래 타겟클래스의 sayHello1() 메소드가 호출된다.
package aophello1;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class LoggingAspect {
@Around("execution(* aophello1.PrintMsg.sayHello1())")
public void myAdvice(ProceedingJoinPoint pjp)
throws Throwable{
System.out.println("메소드 실행전 안녕..."); //메소드 실행전
Object ret = pjp.proceed();
System.out.println("메소드 실행후 안녕..."); //메소드 실행후
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)
 [Src/main/resources/aophello1.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd ">
<aop:aspectj-autoproxy />
<!-- Definition for printMsg bean, 타겟클래스 -->
<bean id="printMsg" class="aophello1.PrintMsg" />
<!-- Definition for logging aspect 충고들이 오여있는 Aspect클래스-->
<bean id="logging" class="aophello1.LoggingAspect"/>
</beans>
3. Spring AOP((Spring Aspect Oriented Programming)
3-2. AOP HelloWorld
3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)
 [HelloMain.java]
package aophello1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("aophello1.xml");
IPrintMsg printMsg = (IPrintMsg) ctx.getBean("printMsg");
//sayHello1만 충고가 내려가도록 되어 있다.
printMsg.sayHello1();
printMsg.sayHello2();
}
}
[결과]
메소드 실행전 안녕...
Hello AOP1...
메소드 실행후 안녕...
Hello AOP2...
3. Spring AOP((Spring Aspect Oriented Programming)
3-3. AOP 충고(Advice)
: 스프링 AOP에서 충고(Advice)는 횡단관심사 기능을 구현한 것인데 다음과 같이 분류한다.
3. Spring AOP((Spring Aspect Oriented Programming)
3-3. AOP 충고(Advice)
: 스프링 AOP에서 충고(Advice)는 횡단관심사 기능을 구현한 것인데 다음과 같이 분류한다.
: Aroud Advice의 앞 단 처리 부분과 Before Advice, Aroud Advice의 뒷 단 처리부
분과 After Returning Advice간 실행순서는 정해져 있지 않고 먼저 추가되는 Advice,
Advisor가 먼저 실행된다.
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
: 프로그래밍적인 방법을 통해 Spring AOP의 기본원리를 이해하자.
STS에서
1. File -> New -> Spring Starter Project
Name : demo-smallmart
Type : MAVEN
Package : onj.hello.aop
2. Core -> AOP 체크
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
 [SmallMartInterface.java]
package onj.hello.aop;
public interface SmallMartInterface {
public void getProducts(String productName) throws Exception;
}
 [SmallMart.java]
package onj.hello.aop;
public class SmallMart implements SmallMartInterface {
public void getProducts(String productName) throws Exception {
System.out.println("[Target Method]getProduct()..." + productName);
throw new Exception("error..."); //주석으로 막고 실행해 보자.
}
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
 [BeforeLoggingAdvice.java]
package onj.hello.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeLogginAdvice implements MethodBeforeAdvice{
public void before(Method method, Object[] args, Object target) throws Throwable {
String findName = (String)args[0];
System.out.println(method.getName() + "(" + findName + "):: 사전충고");
}
}
/**
* 사전 충고용 인터페이스
* 이메소드는 대상메소드, 그 메소드에 전달할 인자, 대상객체에 대한 접근점 제공
* 메소드 인자에 접근 가능하므로 런타임중에 파라미터를 사용하여 충고 구현 가능
*/
public interface MethodBeforeAdvice {
void before(Method method, Object[] args, Object target) throws Throwable ;
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
 [AfterLoggingAdvice.java]
package onj.hello.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class AfterLoggingAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws
Throwable {
System.out.println(method.getName() + "(" + args[0] + ") :: 사후중고" );
}
}
/* 사후 충고(AfterReturning Advice)용 인터페이스 */
public interface AfterReturningAdvice {
void afterReturning(Object returnValue, Method method, Object[] args, Object
target) throws Throwable;
}
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
 [AroundLoggingAdvice.java]
package onj.hello.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundLoggingAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String findName = (String) invocation.getArguments()[0];
String methodName = (String) invocation.getMethod().getName();
System.out.println("[주변충고]" + methodName + "(" + findName + ") 메소드 실행전");
Object obj = invocation.proceed(); // 타켓클래스의 메소드 호출
System.out.println("[주변충고]" + methodName + "(" + findName + ") 메소드 실행후");
return obj;
}
}
/* 이전에 사전,사후 충고를 엮었는
데 주변충고를 통해 둘 다를 엮을
수 있다.*/
public interface
MethodInterceptor {
Object
invoke(MethodInvocation
invocation) throws Throwable;
}
MethodInterceptor 구현 클래스
(주변충고용 클래스)는 대상 메소
드의 실제 호출여부를 제어하며
proceed를 통해 호출 타깃 메소드
호출하며, 원래 메소드의 리턴을
대체 가능하다.
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
 [ThrowsLoggingAdvice.java]
package onj.hello.aop;
import org.springframework.aop.ThrowsAdvice;
public class ThrowsLoggingAdvice implements ThrowsAdvice {
public void afterThrowing(Throwable throwable) {
System.out.println("에러 발생...");
}
}
/* 예외가 발생했을 때의 행위를 정의, marker interface */
public interface ThrowsAdvice { }
구현대상이 없지만 아래의 메소드중 하나를 포함해야 한다.
void afterThrowing(Throwable throwable);
void afterThrowing(Method method, Object[] args, Object target, Throwable
throwable);
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
 [DemoSmallmartApplication.java]
package onj.hello.aop;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoSmallmartApplication {
public static void main(String[] args) {
SpringApplication.run(DemoSmallmartApplication.class, args);
SmallMartInterface target = new SmallMart();
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new BeforeLoggingAdvice());
pf.addAdvice(new AfterLoggingAdvice());
pf.addAdvice(new AroundLoggingAdvice());
pf.addAdvice(new ThrowsLoggingAdvice());
pf.setTarget(target);
try {
SmallMartInterface proxy = (SmallMartInterface)pf.getProxy();
proxy.getProducts("생필품");
}
catch(Exception e) {e.printStackTrace(System.out); }
}
}
DemoSmallmartApplication 클래스에서 마우스 우측버튼 ->
Run As -> Spring Boot App 또는 Java Application으로 실
행 가능
3. Spring AOP((Spring Aspect Oriented Programming)
3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
Any Questions ?
THANK YOU
FOR YOUR ATTENTION
무료국비지원교육 / 구로자바학원 _ 탑크리에듀 교육센터
http://www.topcredu.co.kr

스프링프레임워크 & 마이바티스 무.료 강의자료 제공 (Spring IoC & DI)_ 구로자바학원/구로오라클학원/구로IT학원

  • 1.
    Spring Framework &MyBatis 스프링 프레임워크 & 마이바티스 강의 탑크리에듀 교육센터
  • 2.
    CONTENTS 3. Spring AOP((SpringAspect Oriented Programming) 3.1 AOP 개요 3.2 AOP HelloWorld 3.2.1 AOP HelloWorld(프로그래밍을 통한 AOP 구현) 3.2.2 AOP HelloWorld(XML Schema Based AOP 구현) 3.2.3 HelloWorld(@AspectJ Annotation Based AOP 구현) 3.2.4 생성자 주입(Constructor Injection) – 어노테이션 기반 3.3 AOP 충고(Advice) 3.4 프로그래밍적인 방법을 통한 AOP 구현 (ProxyFactory 이용)
  • 3.
    Chapter 3 Spring AOP((SpringAspect Oriented Programming) ~ 3.4
  • 4.
    3. Spring AOP((SpringAspect Oriented Programming) 3-1. AOP 개요  IoC를 이용하여 협력하는 객체를 쉽게 연결 가능지만 때로는 전체 애플리케이션에 걸쳐 사용되어야 하 는 공통적인 기능(횡단관심사)이 필요할 수도 있다.  DI의 목적이 Application간 결합 도를 떨어뜨리는 것이 목표라면 AOP의 목적은 횡단관심사(Cross- Cutting Concerns, 예외처리, 로깅, 인증, 보안, 트랜잭션)와 이에 영향을 받는 객체간에 결합도를 떨어뜨 리는 것이다. 즉 AOP는 횡단관심사를 모듈화하는 프로그래밍 기법으로 공통적인 기능을 Aspect라 불리 는 한곳에서 정의한다.  새로운 기능을 적용하려고 하는 클래스를 수정할 필요 없이 그런 기능을 어디에 어떻게 적용할 것인지 선언적 또는 어노테이션으로 정의가 가능하다.  각 횡단관심사에 관한 로직이 애플리케이션 전체에 걸쳐 관리되지 않고 Aspect라고 하는 곳에서 관리되 고 어플리케이션은 고유의 비즈니스 로직 처리에 충실할 수 있다.  Logging은 시스템 내에서 거의 모든 경우에 적용하긴 하지만 특정한 비즈니스 로직과는 전혀 관련이 없 다. 만일 AOP방식으로 구현한다면 실제 비즈니즈 로직의 구현을 담당하는 객체는 아무런 로그 관련 객 체 정보가 없고 이 객체의 특정 메소드를 호출하는 시점에 지정된 다른 서비스(로깅)가 실행된다.  횡단 관심사(Cross-Cuitting Concern) : 여러 개의 모듈에 걸치는 시스템 전체적인 부가적인 요구사항을 다룬다. 대표적인 횡단 관심사의 일부 예들 든다면 인증, 로깅,트랜잭션 무결 성, 오류검사, 정책시행  핵심 관심사(Primary Concern) : 각 모듈에서 수행해야 하는 기본적이고 대표적인 업무처리 기능
  • 5.
    3. Spring AOP((SpringAspect Oriented Programming) 3-1. AOP 개요  Springdptj AOP 구현 방법  소스코드에서 직접 AOP 구현 : Proxy Factory 기반 AOP  선언적 AOP 설정 메커니즘 Proxy Factory Bean 사용 : 스프링 Application Context를 XML에 선언적으로 선언하여 빈 정의를 기반으로 AOP 프록시 생성한다. Spring aop 네임스페이스 : aop 네임스페이스를 이용하여 Aspect 및 DI 요구사항을 간단히 정의. Aop 네임 스페이스도 내부적으로 Proxy Factory Bean 사용한다. @Apect J Annotation : @AspectJ방식의 어노테이션을 사용하여 클래스 내에서 AOP 설정이 가능하다, 이 방식은 AspectJ를 기반으로 하고 있으며 AspectJ 라이브러리가 필요하다. 이 역시 스프링에서는 프록시 메커니즘을 이용하는데 Application Context를 부트스트랩 할 때 타깃에 대해 프록시를 생성한다. Spring AOP는 메소드 가로채기로 제한, 만약 그 이상의 기능 (생성자 또는 멤버변수에 대한 가로채기)을 필요로 하는 경우 Proxy 기반 AOP 대신 AspectJ를 이용해서 Aspect를 구현해야 한다.
  • 6.
    3. Spring AOP((SpringAspect Oriented Programming)  스프링의 충고(Advice)는 자바로 작성 : Pointcut의 경우 Advice를 어디에 적용할지를 정의하는 데 XML 설정 파일, AspectJ Expression으로 정의한다. AspectJ는 자바언어를 확장한 형태로 구현. 새로운 도구와 문법을 배워야 한다.  스프링의 Aspect는 실행시간에 만들어진다. 빈을 감싸는 Proxy 객체를 실행시간에 생성하므로 Aspect가 Spring 관련 빈에 위빙(Weaving)된다. Proxy 객체는 타겟 객체로 위장해서 메소드 호출을 가로채고, 타 겟 객체로 호출을 전달한다. 어플리케이션이 실제 Proxy 객체를 필요로 할 때까지 target를 생성하지 않 으므로 즉 Proxy가 실시간으로 생성되므로 Aspect를 위빙 하기 위해 별도 컴파일러가 필요 없다.  스프링은 AOP연맹의 인터페이스를 구현하며 메소드 호출 결합점(Join Point)만 제공한다.
  • 7.
    3. Spring AOP((SpringAspect Oriented Programming)  충고AOP 용어
  • 8.
    3. Spring AOP((SpringAspect Oriented Programming)  충고AOP 용어
  • 9.
    3. Spring AOP((SpringAspect Oriented Programming)  스프링에서 Proxy 객체를 생성하는 방법은 2가지. 1. 대상 객체가 특정 메소드를 공개하는 인터페이스를 구현한다면 JDK의 java.lang.reflect.Proxy 클래스를 이용하며 이 클 래스는 필요한 인터페이스를 구현한 새로운 Proxy 객체를 동적으로 생성할 수 있으며 target 객체의 인터페이스를 통한 호출은 모두 가로채서 Advice를 수행한다. 2. 대상 클래스가 어떤 인터페이스를 구현하고 있지 않다면 CGLIB이라는 라이브러리를 이용하여 대상클래스의 서브클래 스를 생성 시킨다. 이 서브클래스를 생성시킴으로써 스프링은 충고를 엮을 수 있으며 서브클래스에 대한 호출을 대상 클 래스에 위임 할 수 있다. 이 경우 final 메소드는 충고를 받을 수 없으며(final Method는 대상클래스의 서브클래스를 생성 해서 메소드를 재정의 해야 하는데 final인 경우 곤란함) 애플리케이션이 좀 더 느슨하게 결합되게 하기 위해 이 방법보단 인터페이스를 통해 프록시를 만드는 것이 선호된다.  스프링 어스팩트 : 스프링 AOP에서 애스팩트는 Advisor 인터페이스를 구현한 클래스의 인스턴스로 표 시하는데 Advisor를 구현한 몇 개의 클래스를 제공한다. Advisor의 하위 인터페이스로는 IntroductionAdvisor, PointcutAdvisor등이 있는데 PointcutAdvisor 인터페이스는 포인트컷을 사용하여 조인포인트에 어드바이스를 적용하는 모든 Advisor가 구현한다.
  • 10.
    3. Spring AOP((SpringAspect Oriented Programming)  File -> New -> Spring Legacy Project -> Simple Spring Maven 선택 후 프로젝트 명을 “aophello1” 이 라고 입력 후 “Finish” 클릭  단순히 "Hello AOP..." 이라고 출력하는 PrintMsg 클래스의 메소드 sayHello()가 있고 이 클래스에 주변 충고(어라운드 어드바이스, Around Advice)를 추가해 sayHello() 메소드 실행 전/후 필요한 기능 ("메소드 실행 전 안녕...", "메소드 실행 후 안녕...")을 출력하고자 한다. 3-2. AOP HelloWorld 3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)  [IprintMsg.java] package aophello1; public interface IPrintMsg { public void sayHello(); }  [PrintMsg.java] 타겟 클래스(충고가 적용될 클래스, 횡단관심사 기능을 구햔한 클래스 본 예제에서는 간단히 로깅만 하기로 한다. package aophello1; public class PrintMsg implements IPrintMsg { public void sayHello() { System.out.println("Hello AOP..."); } }
  • 11.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)  [MyAroundAdvice.java] 어라운드 어드바이스(AroundAdvice)의 구현체, 충고 MethodInterceptor는 메소드 호출용 어라운드 어드바이스의 표준 인터페이스이다. MethodInvocation은 어드바이스를 추가하기 위한 메소드 호출을 나타내며 이 객체를 사용하면 메소드 호출이 실행되는 시점 (메소드 실행 전/후)을 제어할 수 있다. package aophello1; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class MyAroundAdvice implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("메소드 실행전 안녕..."); Object ret = invocation.proceed(); System.out.println("메소드 실행후 안녕..."); return ret; } }
  • 12.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)  [HelloMain.java] Proxt 빈 객체를 생성후 MyAroundAdvice 및 타겟 객체인 PrintMsg를 위빙하여 프록시 생성 package aophello1; import org.springframework.aop.framework.ProxyFactory; public class HelloMain { public static void main(String[] args) { IPrintMsg target = new PrintMsg(); //Proxy 빈껍데기 생성 ProxyFactory pf = new ProxyFactory(); pf.addAdvice(new MyAroundAdvice()); //충고 add pf.setTarget(target); //타겟 add PrintMsg proxy = (PrintMsg)pf.getProxy(); proxy.sayHello(); } }
  • 13.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-1. AOP HelloWorld(프로그래밍을 통한 AOP 구현)  [HelloMain.java] Proxt 빈 객체를 생성후 MyAroundAdvice 및 타겟 객체인 PrintMsg를 위빙하여 프록시 생성 package aophello1; import org.springframework.aop.framework.ProxyFactory; public class HelloMain { public static void main(String[] args) { IPrintMsg target = new PrintMsg(); //Proxy 빈껍데기 생성 ProxyFactory pf = new ProxyFactory(); pf.addAdvice(new MyAroundAdvice()); //충고 add pf.setTarget(target); //타겟 add PrintMsg proxy = (PrintMsg)pf.getProxy(); proxy.sayHello(); } }  [실행결과] 메소드 실행 전 안녕... Hello AOP... 메소드 실행 후 안녕...
  • 14.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)  File -> New -> Spring Legacy Project -> Simple Spring Maven 선택 후 프로젝트 명을 “aophello1” 이 라고 입력 후 “Finish” 클릭  스프링에서 제공하는 aop Namespace를 이용하는 방법으로 타깃 클래스의 sayHello1(), sayHello2() 메 소드 중 sayHello1() 메소드만 주변충고가 적용되도록 구성한 예제이다.  [pom.xml]에 AOP를 위한 라이브러리 추가 <!-- Spring AOP + AspectJ --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring- framework.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.11</version> </dependency>
  • 15.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)  [IprintMsg.java] package aophello1; public interface IPrintMsg { public void sayHello1(); public void sayHello2(); }  [PrintMsg.java] package aophello1; public class PrintMsg implements IPrintMsg { public void sayHello1() { System.out.println("Hello AOP1..."); } public void sayHello2() { System.out.println("Hello AOP2..."); } }  [LogginAspect.java] // XML Schema Based AOP 구현에서는 Aspect클래스에 충고용 메소드를 정의한다. // 아래 myAdvice가 주변충고용 메소드로 어떤 메소드에 이 충고가 내려갈지는 XML에서 설정을 한다. // pjp.procees() 메소드를 통해 원래 타겟클래스의 sayHello1() 메소드가 호출된다. package aophello1; import org.aspectj.lang.ProceedingJoinPoint; public class LoggingAspect { public void myAdvice(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("메소드 실행전 안녕..."); //메소드 실행 전 Object ret = pjp.proceed(); System.out.println("메소드 실행후 안녕..."); //메소드 실행 후 } }
  • 16.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)  [Src/main/resources/aophello1.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd "> <aop:config> <aop:aspect id="helloAspect" ref="logging"> <!-- ref에는 충고를 담고있는 Aspect가 온다  <aop:pointcut id="selectSayHello1" expression="execution(* aophello1.PrintMsg.sayHello1(..))"/> <!—myAdvice는 Aspect 클래스(logging)의 충고용 메소드--> <aop:around pointcut-ref="selectSayHello1" method="myAdvice"/> </aop:aspect> </aop:config> <!-- Definition for printMsg bean, 타겟클래스 --> <bean id="printMsg" class="aophello1.PrintMsg" /> <!-- Definition for logging aspect 충고들이 오여있는 Aspect클래스--> <bean id="logging" class="aophello1.LoggingAspect"/> </beans>
  • 17.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-2. AOP HelloWorld (XML Schema Based AOP 구현)  [HelloMain.java] package aophello1; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloMain { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("aophello1.xml"); IPrintMsg printMsg = (IPrintMsg) ctx.getBean("printMsg"); //sayHello1만 충고가 내려가도록 되어 있다. printMsg.sayHello1(); printMsg.sayHello2(); } }
  • 18.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)  File -> New -> Spring Legacy Project -> Simple Spring Maven 선택 후 프로젝트 명을 “aophello1” 이라고 입력 후 “Finish” 클릭  스프링에서 제공하는 aop Namespace를 이용하는 방법으로 타깃 클래스의 sayHello1(), sayHello2() 메소드 중 sayHello1() 메소드만 주변충고가 적용되도록 구성한 예제이다.  [pom.xml]에 AOP를 위한 라이브러리 추가 <!-- Spring AOP + AspectJ --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring-framework.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.11</version> </dependency>
  • 19.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)  [IprintMsg.java] package aophello1; public interface IPrintMsg { public void sayHello1(); public void sayHello2(); }  [PrintMsg.java] package aophello1; public class PrintMsg implements IPrintMsg { public void sayHello1() { System.out.println("Hello AOP1..."); } public void sayHello2() { System.out.println("Hello AOP2..."); } }
  • 20.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)  [LogginAspect.java] // Aspect클래스로 충고용 메소드 및 포인트컷을 정의한다. // 아래 myAdvice가 주변충고용 메소드로 메소드 상단에 포인트컷을 정의했다. // pjp.procees() 메소드를 통해 원래 타겟클래스의 sayHello1() 메소드가 호출된다. package aophello1; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @Aspect public class LoggingAspect { @Around("execution(* aophello1.PrintMsg.sayHello1())") public void myAdvice(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("메소드 실행전 안녕..."); //메소드 실행전 Object ret = pjp.proceed(); System.out.println("메소드 실행후 안녕..."); //메소드 실행후 } }
  • 21.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)  [Src/main/resources/aophello1.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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd "> <aop:aspectj-autoproxy /> <!-- Definition for printMsg bean, 타겟클래스 --> <bean id="printMsg" class="aophello1.PrintMsg" /> <!-- Definition for logging aspect 충고들이 오여있는 Aspect클래스--> <bean id="logging" class="aophello1.LoggingAspect"/> </beans>
  • 22.
    3. Spring AOP((SpringAspect Oriented Programming) 3-2. AOP HelloWorld 3-2-3. AOP HelloWorld (@AspectJ Annotation Based AOP 구현)  [HelloMain.java] package aophello1; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloMain { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("aophello1.xml"); IPrintMsg printMsg = (IPrintMsg) ctx.getBean("printMsg"); //sayHello1만 충고가 내려가도록 되어 있다. printMsg.sayHello1(); printMsg.sayHello2(); } } [결과] 메소드 실행전 안녕... Hello AOP1... 메소드 실행후 안녕... Hello AOP2...
  • 23.
    3. Spring AOP((SpringAspect Oriented Programming) 3-3. AOP 충고(Advice) : 스프링 AOP에서 충고(Advice)는 횡단관심사 기능을 구현한 것인데 다음과 같이 분류한다.
  • 24.
    3. Spring AOP((SpringAspect Oriented Programming) 3-3. AOP 충고(Advice) : 스프링 AOP에서 충고(Advice)는 횡단관심사 기능을 구현한 것인데 다음과 같이 분류한다. : Aroud Advice의 앞 단 처리 부분과 Before Advice, Aroud Advice의 뒷 단 처리부 분과 After Returning Advice간 실행순서는 정해져 있지 않고 먼저 추가되는 Advice, Advisor가 먼저 실행된다.
  • 25.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용) : 프로그래밍적인 방법을 통해 Spring AOP의 기본원리를 이해하자. STS에서 1. File -> New -> Spring Starter Project Name : demo-smallmart Type : MAVEN Package : onj.hello.aop 2. Core -> AOP 체크
  • 26.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
  • 27.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
  • 28.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)  [SmallMartInterface.java] package onj.hello.aop; public interface SmallMartInterface { public void getProducts(String productName) throws Exception; }  [SmallMart.java] package onj.hello.aop; public class SmallMart implements SmallMartInterface { public void getProducts(String productName) throws Exception { System.out.println("[Target Method]getProduct()..." + productName); throw new Exception("error..."); //주석으로 막고 실행해 보자. } }
  • 29.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)  [BeforeLoggingAdvice.java] package onj.hello.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class BeforeLogginAdvice implements MethodBeforeAdvice{ public void before(Method method, Object[] args, Object target) throws Throwable { String findName = (String)args[0]; System.out.println(method.getName() + "(" + findName + "):: 사전충고"); } } /** * 사전 충고용 인터페이스 * 이메소드는 대상메소드, 그 메소드에 전달할 인자, 대상객체에 대한 접근점 제공 * 메소드 인자에 접근 가능하므로 런타임중에 파라미터를 사용하여 충고 구현 가능 */ public interface MethodBeforeAdvice { void before(Method method, Object[] args, Object target) throws Throwable ; }
  • 30.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)  [AfterLoggingAdvice.java] package onj.hello.aop; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class AfterLoggingAdvice implements AfterReturningAdvice { public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println(method.getName() + "(" + args[0] + ") :: 사후중고" ); } } /* 사후 충고(AfterReturning Advice)용 인터페이스 */ public interface AfterReturningAdvice { void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable; }
  • 31.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)  [AroundLoggingAdvice.java] package onj.hello.aop; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AroundLoggingAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { String findName = (String) invocation.getArguments()[0]; String methodName = (String) invocation.getMethod().getName(); System.out.println("[주변충고]" + methodName + "(" + findName + ") 메소드 실행전"); Object obj = invocation.proceed(); // 타켓클래스의 메소드 호출 System.out.println("[주변충고]" + methodName + "(" + findName + ") 메소드 실행후"); return obj; } } /* 이전에 사전,사후 충고를 엮었는 데 주변충고를 통해 둘 다를 엮을 수 있다.*/ public interface MethodInterceptor { Object invoke(MethodInvocation invocation) throws Throwable; } MethodInterceptor 구현 클래스 (주변충고용 클래스)는 대상 메소 드의 실제 호출여부를 제어하며 proceed를 통해 호출 타깃 메소드 호출하며, 원래 메소드의 리턴을 대체 가능하다.
  • 32.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)  [ThrowsLoggingAdvice.java] package onj.hello.aop; import org.springframework.aop.ThrowsAdvice; public class ThrowsLoggingAdvice implements ThrowsAdvice { public void afterThrowing(Throwable throwable) { System.out.println("에러 발생..."); } } /* 예외가 발생했을 때의 행위를 정의, marker interface */ public interface ThrowsAdvice { } 구현대상이 없지만 아래의 메소드중 하나를 포함해야 한다. void afterThrowing(Throwable throwable); void afterThrowing(Method method, Object[] args, Object target, Throwable throwable);
  • 33.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)  [DemoSmallmartApplication.java] package onj.hello.aop; import org.springframework.aop.framework.ProxyFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoSmallmartApplication { public static void main(String[] args) { SpringApplication.run(DemoSmallmartApplication.class, args); SmallMartInterface target = new SmallMart(); ProxyFactory pf = new ProxyFactory(); pf.addAdvice(new BeforeLoggingAdvice()); pf.addAdvice(new AfterLoggingAdvice()); pf.addAdvice(new AroundLoggingAdvice()); pf.addAdvice(new ThrowsLoggingAdvice()); pf.setTarget(target); try { SmallMartInterface proxy = (SmallMartInterface)pf.getProxy(); proxy.getProducts("생필품"); } catch(Exception e) {e.printStackTrace(System.out); } } } DemoSmallmartApplication 클래스에서 마우스 우측버튼 -> Run As -> Spring Boot App 또는 Java Application으로 실 행 가능
  • 34.
    3. Spring AOP((SpringAspect Oriented Programming) 3-4. 프로그래밍적인 방법을 통한 AOP 구현(ProxyFactory 이용)
  • 35.
    Any Questions ? THANKYOU FOR YOUR ATTENTION 무료국비지원교육 / 구로자바학원 _ 탑크리에듀 교육센터 http://www.topcredu.co.kr