CONTENTS 3 Spring AOPSpring Aspect Oriented Programming 3

  • Slides: 23
Download presentation

CONTENTS 3. Spring AOP((Spring Aspect Oriented Programming) 3. 8 @Aspect. J Annotation을 이용한 AOP

CONTENTS 3. Spring AOP((Spring Aspect Oriented Programming) 3. 8 @Aspect. J Annotation을 이용한 AOP 3. 8. 1 @Aspect. J Annotation을 이용한 AOP – Aspect 선언 3. 8. 2 @Aspect. J Annotation을 이용한 AOP – Advice 선언 3. 8. 3 @Aspect. J Annotation을 이용한 AOP – Pointcut 선언 3. 8. 4 @Aspect. J Annotation을 이용한 AOP – aspectj expression 3. 8. 5 @Aspect. J Annotation을 이용한 AOP – 예제 3. 9 스프링 선언적 AOP에 대한 고려사항(@Aspect. J vs XML)

Chapter 3 Spring AOP((Spring Aspect Oriented Programming) ~ 3. 7

Chapter 3 Spring AOP((Spring Aspect Oriented Programming) ~ 3. 7

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP §

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP § Spring AOP와 JDK 1. 5 이상인 경우 어노테이션을 이용하여 어드바이스를 선언 할 수 있다. § @Aspect. J 방식은 Aspect. J 5 버전에서 소개되었으며, Spring은 2. 0 버전부터 Aspect. J 5 어노테이션을 지원한다 § 타겟 메소드에 어드바이스를 적용할 때는 Aspect. J의 위빙 메커니즘이 아니라 자체 프록시 메커니즘을 이용한다. § @Aspect. J를 사용하기 위해서 XML설정 파일에 <aop: aspectj-autoproxy/> 태그를 설정에 추가해야하며 클래스에@Aspect 어노테이 션을 추가하여 Aspect를 생성해야 한다. § @Pointcut으로 포인트컷을 정의하거나 @Before, @After등 충고를 정의할 때 Aspect. J Expression을 정의하여 포인트컷을 지정할 수 있다. 3 -8 -1. @Aspect. J Annotation을 이용한 AOP – Aspect 선언 § 자바설정을 이용하여 Aspect. J를 사용하는 방법 @Configuration @Enable. Aspect. JAuto. Proxy public class App. Config { } @Aspect public class User. Aspect { // USer. Service+ : 인스턴스의 타입이 User. Service 이거나 하위타입을 의미 @Before("execution(* x. y. z. User. Service+. *(. . ))") public void user. Advice(){ System. out. println("find my advice before your task. "); } } @Configuration @Enable. Aspect. JAuto. Proxy public class Aspect. JAuto. Proxy. Config { @Bean public User. Service user. Service(){ return new User. Service(); } @Bean public User. Aspect user. Aspect(){ return new User. Aspect(); } }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -1. @Aspect. J Annotation을 이용한 AOP – Aspect 선언 XML설정을 이용하여 Aspect. J를 사용하는 방법<aop: aspectj-autoproxy/> <bean id="my. Aspect" class=“ojc. aop. Ojc. Aspect“/> package ojc. aop; import org. aspectj. lang. annotation. Aspect; @Aspect public class Ojc. Aspect { …… } 위 XML절정은 @Component를 이용하면 아래처럼 가능하다. (XML에서 빈으로 정의하지 않을 경우 @Component, @Service, @Named와 같은 Annotation을 기술하면 된다. ) <aop: aspectj-autoproxy/> package ojc. aop; import org. aspectj. lang. annotation. Aspect; @Aspect @Component public class Ojc. Aspect { …… }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -2. @Aspect. J Annotation을 이용한 AOP – Advice 선언 Before advice : Before advice는 @Before 어노테이션을 사용한다. After returning advice : After returing 충고는 정상적으로 메소드가 실행될 때 수행된다. After returning 충고는 @After. Returing 어노테이션을 사용한다. After throwing advice : After throwing 충고는 메소드가 수행 중 예외사항을 반환하고 종료하는 경우 수행된다. After throwing 충고는 @After. Throwing 어노테이션을 사용한다. After (finally) advice : After (finally) 충고는 메소드 수행 후 무조건 수행된다. After (finally) 충고는 @After 어노테이 션을 사용한다. Around advice : Around 충고는 메소드 수행 전후에 수행된다. Around 충고는 @Around 어노테이션을 사용한다. @Around 충고는 대상 메소드의 반환 값(return value)를 변경 가능하지만 , After returning 충고는 반환 값을 참 조 가능하지만 변경할 수는 없다.

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -2. @Aspect. J Annotation을 이용한 AOP – Advice 선언 사전충고(@Before) @Before 어노테이션을 사용하며 포인트컷 메소드가 실행되기 전에 충고가 적용된다. @Aspect public class Before. Example { @Before(“x. y. My. Class. data. Access. Operation()") public void do. Access. Check 1() { //. . . } @Before("execution(* x. y. My. Class. *(. . ))") public void do. Access. Check 2() { //. . . } }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -2. @Aspect. J Annotation을 이용한 AOP – Advice 선언 예외충고(@After. Throwing) @After. Throwing 어노테이션을 사용하며 포인트컷 메소드에서 예외가 발생할 때 충고 가 적용된다. @Aspect public class After. Throwing. Example { @After. Throwing(“x. y. My. Class. data. Access. Operation()") public void do. Recovery. Actions 1() { //. . . } // 리턴값을 ret. Val로 받음, throwing 속성의 값은 어드바이스 메소드의 파라미터와 이름이 // 같아야 하며 예외가 그 변수로 넘어온다. @After. Throwing( pointcut=“x. y. My. Class. data. Access. Operation()", throwing="ex") public void do. Recovery. Actions 2(Data. Access. Exception ex) { //. . . } }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -2. @Aspect. J Annotation을 이용한 AOP – Advice 선언 사후충고(@After) @After 어노테이션을 사용한다. 포인트컷 메소드가 실행된 후(정상종료 여부와 관계없 이) 충고가 적용된다. @Aspect public class After. Example { @After(“x. y. My. Class. data. Access. Operation()") public void do. Release. Lock() { //. . . } }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -2. @Aspect. J Annotation을 이용한 AOP – Advice 선언 [참고] Stop. Watch 사용법 1. System 클래스의 current. Time. Millis() 메소드 이용 1970년 1월 1일 자정부터 현재까지 카운트된 시간을 ms(milliseconds) 단위로 표시한다. long start. Time = System. current. Time. Millis(); // 특정 로직이나 메소드 호출 long elapsed. Time = System. current. Time. Millis() - start. Time; System. out. println(elapsed. Time + " ms"); 2. System 클래스의 nano. Time() 메소드 이용 nano. Time 메서드는 현재 Java 가상머신의 high-resolution 시간값을 ns(nano sec. ) 단위로 반환한다. 3. Common-lang의 Stop. Watch 클래스 start(), stop() 메소드 이용 long start. Time = System. nano. Time(); // 특정 로직이나 메소드 호출 import org. apache. commons. lang. time. Stop. Watch; long endtime = System. nano. Time(); long elapsed. Time = start. Time - endtime; stop. Watch. start(); System. out. println(elapsed. Time + " ns"); do. Some. Task(5000); stop. Watch. stop(); System. out. println("Time: " + stop. Watch. get. Time()); // Time: 5000 4. 스프링 프레임워크의 Stop. Watch 클래스의 start(), stop() 이용 import org. springframework. util. Stop. Watch; stop. Watch. start(); List<Tuple> emps = emp. Service. get. Ename. Dname. Top 5(deptno); stop. Watch. stop(); log. info(">>>>> get. Ename. Dname. Top 5(Time) : " + stop. Watch. get. Total. Time. Seconds());

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -3. @Aspect. J Annotation을 이용한 AOP – Pointcut 선언 @Pointcut 어노테이션을 사용한다. @Pointcut("execution(* onj. aop. *. *(. . ))") private void mypointcut() { } // pointcut expression // pointcut signature @Before("mypointcut ()") public void my. Before. Advice(Join. Pointjoin. Point, int. Value) {. . . }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -3. @Aspect. J Annotation을 이용한 AOP – Pointcut 선언 포인트컷 지정자(Pointcut Designators) //메소드가 어떤 패키지에 있던지 public 메소드 [Aspect 클래스 작성 예] 라면 충고적용 @Aspect //애스팩트 클래스임을 표시 @Pointcut("execution(public * *(. . ))") public class My. Advice { private void any. Public. Operation() {} @Pointcut("execution(* onj. edu. aop 11. . hello*(int)) && args(int. Value)") public void hello. Exec(int int. Value) {} //메소드가 onj 패키지 또는 부 패키지안의 타입 이라면 충고적용 @Pointcut("bean(my. Dependency*)") @Pointcut("within(onj. . *)") public void in. My. Dependency() {} private void in. Trading() {} //@Aspect. J 는 &&, aop 네임스페이스는 and //위 두포인트컷의 AND 조건을 만족하는 경우 충 @Before("hello. Exec(int. Value) && in. My. Dependency()") 고가 적용 public void my. Before. Advice(Join. Pointjoin. Point, int. Value) {. . . } @Pointcut("any. Public. Operation() && in. Trading()") //Around Advice private void trading. Operation() {} @Around("hello. Exec(int. Value)") public my. Around. Advice(Proceeding. Join. Point join. Point, int. Value) throws Throwable {. . . } //메소드가 onj. dao 패키지 또는 부 패키지안의 타입이라면 충고적용 @Pointcut("within(onj. dao. . *)") //. . . }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -4. @Aspect. J Annotation을 이용한 AOP – aspectj expression • bean(oraclejava*) : 이름이 oraclejava로 시작되는 모든 빈의 메소드가 포인트 컷 • bean(*data. Source) || bean(*Data. Source): 빈 이름이 “data. Source” 나 “Data. Source” 으로 끝나는 모든 빈의 메소드가 포인트 컷 • !bean(onjoraclejava) : onjoraclejava빈을 제외한 모든 빈의 메소드가 포인트 • this(onj. aop. Small. Mart. Interface): 현재 실행중인 인스턴스가 Small. Mart. Interface 이름의 빈과 타입이 같은 경우 포인트컷, Small. Mart인터페이스를 구현했다면 모든 메소드가 포인트컷 • target(onj. aop. Small. Mart. Interface): 타겟 오브젝트가 Small. Mart. Interface를 구현했다면 모든 메소드가 포인트컷 • args(java. io. Serializable) : 메소드가 매개변수가 하나이고 Serializable인터페이스를 타입이라면 포인트컷 • @target(org. springframework. transaction. annotation. Transactional): 타겟 오브젝트가 org. springframework. transaction. annotation. Transactional 어노테이션(@Transactional)을 가진다면 포인트컷 • @within(org. springframework. transaction. annotation. Transactional): 타겟 오브젝트의 선언된 타입이 @Trtansactional 어노테이 션을 가진다면 포인트컷 • @annotation(org. springframework. transaction. annotation. Transactional): 실행 메소드가 @Transactional 어노테이션을 가진다 면 포인트컷 • @args(x. y. Annotation. Required): 파라미터를 하나 가지며 넘어오는 아규먼트의 런타임 타입이 @Annotation. Required 타입이라면 포인트컷

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -5. @Aspect. J Annotation을 이용한 AOP – 예제 : 이전에 작성한 AOP Name. Space를 이용한 Small. Mart 예제를 @Aspect. J Annotation을 이용하여 변경해 보자. [Small. Mart. Interface. java] STS에서 package onj. hello. aop 3; 1. File -> New -> Spring Starter Project public interface Small. Mart. Interface { Name : demo-smallmart 3 public String get. Products(String Type : MAVEN product. Name) throws Exception; Package : onj. hello. aop 3 } 다음화면에서 Core -> AOP 체크 2. @Inject를 사용하기 위해 의존성 추가 <dependency> <group. Id>javax. inject</group. Id> <artifact. Id>javax. inject</artifact. Id> <version>1</version> </dependency>

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -5. @Aspect. J Annotation을 이용한 AOP – 예제 [Small. Mart. java] package onj. hello. aop 3; @Component public class Small. Mart implements Small. Mart. Interface { public String get. Products(String product. Name) throws Exception { return "[Target Method]get. Product(). . . " + product. Name; //throw new Exception("error. . . "); } }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -5. @Aspect. J Annotation을 이용한 AOP – 예제 [Small. Mart. Aspect. java] package onj. hello. aop 3; @Component @Aspect public class Small. Mart. Aspect { @Pointcut("execution(* onj. hello. aop 3. Small. Mart. Interface. get. Products(. . ))") public void get. Product 1() { } @Pointcut("args(String)") public void get. Product 2() { } // 사전충고 : 타겟클래스의 메소드 실행 전 충고실행 @Before("get. Product 1() && get. Product 2()") public void log. Before(Join. Point join. Point) { System. out. println("Before Advice --> log. Before(). . . "); join. Point. get. Signature(). get. Name(); } // 사후충고(after) : 타겟클래스의 메소드 실행후 충고 실행, 오류가 발생해도 실행 @After("get. Product 1()") public void log. After(Join. Point join. Point) { System. out. println("After Advice --> log. After(). . . "); join. Point. get. Signature(). get. Name(); } // 사후충고(after returning) : 타겟클래스의 메소드 정상 리턴된 후 실행 // returning 속성으로 리턴값을 받을 수 있다. @After. Returning(pointcut = "get. Product 1()", returning = "result") public void log. After. Returning(Join. Point join. Point, Object result) { System. out. println("After. Returning Advice --> log. After. Returning(). . . "); join. Point. get. Signature(). get. Name(); System. out. println("return value is " + result); }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -5. @Aspect. J Annotation을 이용한 AOP – 예제 [Small. Mart. Aspect. java] // 주변충고 : 타겟클래스의 메소드 실행 전후에 충고 실행 @Around("get. Product 1()") public String log. Around(Proceeding. Join. Point join. Point) throws Throwable { System. out. println("Around Advice[전] --> log. Around(). . . "); join. Point. get. Signature(). get. Name(); Arrays. to. String(join. Point. get. Args()); // 타겟 객체의 원래 메소드 실행 String s = (String) join. Point. proceed(); System. out. println("Around Advice[후] --> log. Around(). . . "); // 원래 타겟클래스의 메소드 리턴값을 대체시킴 return "이문장으로원래 타겟메소드(get. Products) 리턴이 대체됨!!"; } // 예외충고 : 예외가 발생될때 충고 실행 @After. Throwing(pointcut = " get. Product 1()", throwing = "error") // error는 실행되는 메소드에서 던지는 예외객체 public void log. After. Throwing(Join. Point join. Point, Throwable error) { System. out. println("예외충고 --> log. After. Throwing(). . . "); join. Point. get. Signature(). get. Name(); System. out. println("Exception " + error); } }

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3

3. Spring AOP((Spring Aspect Oriented Programming) 3 -8. @Aspect. J Annotation을 이용한 AOP 3 -8 -5. @Aspect. J Annotation을 이용한 AOP – 예제 [Demo. Small. Mart 3 Application. java] package onj. hello. aop 3; import org. springframework. beans. factory. annotation. Autowired; import org. springframework. boot. Command. Line. Runner; import org. springframework. boot. Spring. Application; import org. springframework. boot. autoconfigure. Spring. Boot. Application; import org. springframework. context. annotation. Bean; import org. springframework. context. annotation. Enable. Aspect. JAuto. Proxy; @Spring. Boot. Application public class Demo. Smallmart 3 Application implements Command. Line. Runner { public static void main(String[] args) throws Exception { Spring. Application. run(Demo. Smallmart 3 Application. class, args); } @Inject private Small. Mart. Interface small. Mart; public void run(String. . . args) throws Exception { this. small. Mart. get. Products("과자"); } }

THANK YOU FOR YOUR ATTENTION Any Questions ? 무료국비지원교육 / 구로자바학원 _ 탑크리에듀 교육센터

THANK YOU FOR YOUR ATTENTION Any Questions ? 무료국비지원교육 / 구로자바학원 _ 탑크리에듀 교육센터 http: //www. topcredu. co. kr