최신글
hyeonga_code
Spring_AOP 심화 실습_4. 다양한 AOP 실습 본문
반응형
- 글이 없는 경우 발생할 예외를 작성합니다.
- sts.spring.board.vo > ArticleNotFoundException.java 클래스 생성
=====
1
2
3
4
5
6
|
package sts.spring.board.vo;
public class ArticleNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
}
|
- Read 서비스를 제공하는 인터페이스를 작성합니다.
- sts.spring.board.service > ReadArticleService.java 인터페이스 생성
=====
1
2
3
4
5
6
7
8
9
|
package sts.spring.board.service;
import sts.spring.board.vo.ArticleNotFoundException;
import sts.spring.board.vo.ArticleVO;
public interface ReadArticleService {
ArticleVO getArticleAndIncreaseReadCount(int id) throws ArticleNotFoundException;
}
|
- Read 서비스를 구현하는 클래스 작성
- sts.spring.board.service > ReadArticleServiceImpl.java 클래스 생성
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package sts.spring.board.service;
import sts.spring.board.vo.ArticleNotFoundException;
import sts.spring.board.vo.ArticleVO;
public class ReadArticleServiceImpl implements ReadArticleService {
@Override
public ArticleVO getArticleAndIncreaseReadCount(int id) throws ArticleNotFoundException {
if(id == 0)
throw new ArticleNotFoundException();
return new ArticleVO();
}
}
|
- sts.spring.common > LoggingAdvice.java 클래스 생성
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package sts.spring.common;
public class LoggingAdvice {
public void before() {
System.out.println("LogA >> Before method");
}
public void afterReturning(Object ret) {
System.out.println("LogA >> After method [ return value : " + ret + "]");
}
public void afterThrowing(Throwable ex) {
System.out.println("LogA >> During method exception [ exception : " + ex.getClass().getName() + "]");
}
public void afterFinally() {
System.out.println("LogA >> Complete method");
}
}
|
- 실습용 캐시 서비스를 제공할 Advice 클래스를 작성합니다.
- sts.spring.common > ArticleCacheAdvice.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
|
package sts.spring.common;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.ProceedingJoinPoint;
import sts.spring.board.vo.ArticleVO;
public class ArticleCacheAdvice {
private Map<Integer, ArticleVO> cache = new HashMap<Integer, ArticleVO>();
// ArticleVO를 캐싱하는 메소드
public ArticleVO cache(ProceedingJoinPoint joinPoint) throws Throwable {
Integer id = (Integer) joinPoint.getArgs()[0];
ArticleVO article = cache.get(id);
if(article != null) {
System.out.println("_ArticleCacheAdvice : Article[" + id + "]");
}
ArticleVO ret = (ArticleVO) joinPoint.proceed();
if(ret != null) {
cache.put(id, ret);
System.out.println("_ArticleCacheAdvice : Article[" + id + "]");
}
return ret;
}
}
|
- 파라미터 접근 실습용 추적 정보 제공하는 Advice 클래스 작성하기
- sts.spring.common > UpdateMemberInfoTraceAdvice.java 클래스 생성
=====
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package sts.spring.common;
import org.aspectj.lang.JoinPoint;
import sts.spring.member.vo.UpdateInfo;
public class UpdateMemberInfoTraceAdvice {
public void traceReturn(JoinPoint joinPoint, boolean result, String memberId, UpdateInfo info) {
System.out.println("__TraceReturn___________");
System.out.println(" - result : " + result);
System.out.println(" - memberId : " + memberId);
System.out.println(" - Updateinfo : " + info);
}
}
|
- applicationContextTwo.xml 파일 생성
=====
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
|
<?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.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- advice 빈을 등록합니다. -->
<bean id="loggingAdvice" class="sts.spring.common.LoggingAdvice" />
<bean id="cacheAdvice" class="sts.spring.common.ArticleCacheAdvice" />
<bean id="traceAdvice" class="sts.spring.common.UpdateMemberInfoTraceAdvice" />
<aop:config>
<!-- 모든 public 메소드를 대상으로 적용하는 aspect입니다. -->
<aop:aspect id="loggingAspect" ref="loggingAdvice" order="1">
<aop:pointcut id="publicMethod" expression="execution(public * sts.spring..*(..))"/>
<aop:before method="before" pointcut-ref="publicMethod" />
<aop:after-returning method="afterReturning" pointcut-ref="publicMethod" returning="ret"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="publicMethod" throwing="ex" />
<aop:after method="afterFinally" pointcut-ref="publicMethod" />
</aop:aspect>
<!-- ReadArticleServiceImpl의 모든 public 메소드를 대상으로 적용하는 aspect입니다. -->
<aop:aspect id="cacheAspect" ref="cacheAdvice" order="2">
<aop:around method="cache" pointcut="execution(public * *..ReadArticleServiceImpl.*(..))" />
</aop:aspect>
<!-- MemberService의 모든 public 메소드를 대상으로 적용하는 aspect입니다. -->
<aop:aspect id="traceAspect" ref="traceAdvice" order="3">
<aop:after-returning method="traceReturn" pointcut="args(memberId, info)" returning="result" arg-names="joinPoint, result, memberId, info"/>
</aop:aspect>
</aop:config>
<bean id="readArticleService" class="sts.spring.board.service.ReadArticleServiceImpl" />
<bean id="memberService" class="sts.spring.member.service.MemberServiceImpl" />
</beans>
|
- 테스트 할 메인 클래스를 작성합니다.
- sts.spring.board.controller > MainTwo.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
61
62
63
64
65
66
67
68
69
|
package sts.spring.board.controller;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import sts.spring.board.service.ReadArticleService;
import sts.spring.board.vo.ArticleNotFoundException;
import sts.spring.board.vo.ArticleVO;
import sts.spring.member.vo.MemberService;
import sts.spring.member.vo.UpdateInfo;
public class MainTwo {
public static void main(String[] args) {
// 컨테이너를 생성합니다.
String[] configLocations = new String[] { "applicationContextTwo.xml" };
AbstractApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
// 빈으로 등록된 값을 사용합니다.
ReadArticleService readArticleService = context.getBean("readArticleService", ReadArticleService.class);
try {
// 1번글을 얻어와 캐시에 저장합니다.
ArticleVO article1 = readArticleService.getArticleAndIncreaseReadCount(1);
// 캐시에 저장되어 있던 1번 글을 가져옵니다.
ArticleVO article2 = readArticleService.getArticleAndIncreaseReadCount(1);
// 값이 같은 경우 : 캐시에 넣은 값을 가져오는 것입니다.
System.out.println("article1 == article2 : " + (article1 == article2));
// 0번 글은 얻어올 수 없으므로 예외 처리를 확인할 수 있습니다.
readArticleService.getArticleAndIncreaseReadCount(0);
} catch (ArticleNotFoundException e) { }
// 정보를 불러옵니다.
MemberService memberService = context.getBean("memberService", MemberService.class);
// 내용을 수정하고 추적 정보를 확인할 수 있습니다.
memberService.update("javaline", new UpdateInfo());
context.close();
/*
LogA >> Before method
_ArticleCacheAdvice : Article[1]
LogA >> After method [ return value : sts.spring.board.vo.ArticleVO@45a37759]
LogA >> Complete method
LogA >> Before method
_ArticleCacheAdvice : Article[1]
_ArticleCacheAdvice : Article[1]
LogA >> After method [ return value : sts.spring.board.vo.ArticleVO@63611043]
LogA >> Complete method
article1 == article2 : false
LogA >> Before method
LogA >> During method exception [ exception : sts.spring.board.vo.ArticleNotFoundException]
LogA >> Complete method
LogA >> Before method
+ MemberServiceImpl.update()
__TraceReturn___________
- result : true
- memberId : javaline
- Updateinfo : sts.spring.member.vo.UpdateInfo@3f57bcad
LogA >> After method [ return value : true]
LogA >> Complete method
*/
}
}
|
반응형
'Spring' 카테고리의 다른 글
Spring_AOP 심화 실습_@Aspect 어노테이션 활용한 다양한 Advice 적용 (1) | 2024.01.09 |
---|---|
Spring_AOP 심화 실습_5. 어노테이션 활용하기 (0) | 2024.01.09 |
Spring_AOP 심화 실습_ 3. XML 설정 이용하기 (0) | 2024.01.08 |
Spring_AOP 심화 실습_메이븐 프로젝트_2. 기본 구조 작성하기 (0) | 2024.01.08 |
Spring_AOP 심화 실습_ 1. 기본 설정 (0) | 2024.01.08 |