티스토리 뷰
수업 4일차
AOP why? 시스템을 핵심 관심사항과 공통관심사항으로 구분하고 공통 관심 사항의 효율적 개발 및 유지보수를 위해 적용하는 기술
- oop의 중복 작업 피할 수 있다.
how? 공통 관심 사항을 구현(정의)한 bean 생성
적용 대상을 지정 (pointcut : within(), execution(), bean())
적용 시점을 지정 (advice : before, after-returning, after-throwing, after, around)
AOP
ParamCheckAspect.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 | package aop.common; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; public class ParamCheckAspect { private Log log = LogFactory.getLog(getClass()); /** * 현 시스템에서 메서드 실행 전 * 넘어오는 잘못된 인자값(null or "")을 입력 받는 경우 * log.warn(클래스명 메서드명 인자값)으로 로깅 처리 */ public void checkLogging(JoinPoint point){ Object args[] = point.getArgs(); for(int i=0 ; i < args.length ; i++){ if(args[i] == null || args[i].equals("")){ log.warn("잘못된 입자값 : "+point.getClass().getName()+" "+point.getSignature().getName()+" "); } } } } |
CustomerService.java
1 2 3 4 5 6 7 8 9 10 11 | package kosta.model; public class CustomerService { public void insertCustomer(String ssn){ System.out.println("insert customer..."+ssn); } public void findCustomer(String ssn, String address){ System.out.println("find customer.."+ssn+" "+address); } } |
MemberService.Java
1 2 3 4 5 6 7 | package kosta.model; public class MemberService { public void deleteMember(String id){ System.out.println("member delete..."+id); } } |
TestAOP.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 | package test; import kosta.model.CustomerService; import kosta.model.MemberService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAOP { /** * 현 시스템에서 메서드 실행 전 * 넘어오는 잘못된 인자값(null or "")을 입력 받는 경우 * log.warn(클래스명 메서드명 인자값)으로 로깅 처리 * * 1. 공통관심사항을 정의한 bean * aop.common.ParamCheckAspect class의 * checkLogging(JoinPoint) * 2. 적용대상 pointcut : within(kosta.model.*) * kosta.model package 이하의 모든 클래스의 * 모든 메서드 * 3. 적용시점 advice : before */ public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "aop.xml"); CustomerService cs = (CustomerService)context.getBean("customerService"); MemberService ms = (MemberService)context.getBean("memberService"); cs.findCustomer("90", null); cs.insertCustomer("java"); ms.deleteMember(""); } } |
aop.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?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.xsd" > <bean id="customerService" class="kosta.model.CustomerService"></bean> <bean id="memberService" class="kosta.model.MemberService"></bean> <bean id="checkAspect" class="aop.common.ParamCheckAspect"></bean> <aop:config> <aop:pointcut expression="within(kosta.model.*)" id="checkPointCut"/> <aop:aspect ref="checkAspect"> <aop:before method="checkLogging" pointcut-ref="checkPointCut"/> </aop:aspect> </aop:config> </beans> |
log4j.propertis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | log4j.rootLogger = warn,stdout log4j.additivity.aop.common=false log4j.category.aop.common=debug,stdout log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender log4j.appender.dailyfile.File = C:\\nigth-spring\\logfile.log log4j.appender.dailyfile.Append = true log4j.appender.dailyfile.DatePattern='.'yyyy-MM-dd log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout log4j.appender.dailyfile.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n |
[결과]
WARN ({main} ParamCheckAspect.java[checkLogging]:19) [2013-04-25 20:25:08,822] - 잘못된 입자값 : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint findCustomer
find customer..90 null
insert customer...java
WARN ({main} ParamCheckAspect.java[checkLogging]:19) [2013-04-25 20:25:08,842] - 잘못된 입자값 : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint deleteMember
member delete...
AOP-execution
ParamCheckAspect.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 | package aop.common; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; public class ParamCheckAspect { private Log log = LogFactory.getLog(getClass()); /** * 현 시스템에서 메서드 실행 전 * 넘어오는 잘못된 인자값(null or "")을 입력 받는 경우 * log.warn(클래스명 메서드명 인자값)으로 로깅 처리 */ public void checkLogging(JoinPoint point){ Object args[] = point.getArgs(); for(int i=0 ; i < args.length ; i++){ if(args[i] == null || args[i].equals("")){ log.warn("잘못된 입자값 : "+point.getClass().getName()+" "+point.getSignature().getName()+" "); } } } } |
CustomerService.java
1 2 3 4 5 6 7 8 9 10 | package kosta.model; public class CustomerService { public void insertCustomer(String ssn){ System.out.println("insert customer..."+ssn); } public void findCustomer(String ssn, String address){ System.out.println("find customer.."+ssn+" "+address); } } |
MemberService.java
1 2 3 4 5 6 7 | package kosta.model; public class MemberService { public void deleteMember(String id){ System.out.println("member delete..."+id); } } |
BoardDao.java
1 2 3 4 5 6 7 8 9 10 11 | package kosta.model.dao; public class BoardDao { public void findContent(String content){ System.out.println("findContent..."+content); } public void findContent2(String content2, int i){ System.out.println(content2+" "+i); } } |
TestAOP.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 | package test; import kosta.model.CustomerService; import kosta.model.MemberService; import kosta.model.dao.BoardDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAOP { /** * 현 시스템에서 메서드 실행 전 * 넘어오는 잘못된 인자값(null or "")을 입력 받는 경우 * log.warn(클래스명 메서드명 인자값)으로 로깅 처리 * * 1. 공통관심사항을 정의한 bean * aop.common.ParamCheckAspect class의 * checkLogging(JoinPoint) * 2. 적용대상 pointcut : within(kosta.model.*) * kosta.model package 이하의 모든 클래스의 * 모든 메서드 * 3. 적용시점 advice : before * ------------------------------------------------------------------------------------------ * springaop3 의 예제를 변경 * kosta.model 이하의 모든 하위 package의 모든 클래스의 * find로 시작되는 method만 위 기능(param check logging - warn)을 적용한다. * */ public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "aop.xml"); CustomerService cs = (CustomerService)context.getBean("customerService"); MemberService ms = (MemberService)context.getBean("memberService"); BoardDao dao = (BoardDao)context.getBean("boardDao"); cs.findCustomer("90", null); cs.insertCustomer("java"); ms.deleteMember(""); dao.findContent(""); dao.findContent2("", 2); } } |
aop.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 | <?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.xsd" > <bean id="customerService" class="kosta.model.CustomerService"></bean> <bean id="memberService" class="kosta.model.MemberService"></bean> <bean id="checkAspect" class="aop.common.ParamCheckAspect"></bean> <bean id="boardDao" class="kosta.model.dao.BoardDao"></bean> <aop:config> <!-- pointcut 수정 - expression within(kosta.model.*)이하의 모든 package의 모든 클래스의 find계열의 메서드만 적용대랑으로 변경한다. publoc :접근제어자 *:리턴 타입 kosta.model.. : kosta.model package 이하의 모든 package의 ..(이하 모든 하위 package) * : 모든 클래스명 find* : find로 시작하는 모든 메서드 (..) : 매개변수 0~다수 --> <aop:pointcut expression="execution(public * kosta.model..*.find*(String))" id="checkPointCut"/> <aop:aspect ref="checkAspect"> <aop:before method="checkLogging" pointcut-ref="checkPointCut"/> </aop:aspect> </aop:config> </beans> |
log4j.propertis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | log4j.rootLogger = warn,stdout log4j.additivity.aop.common=false log4j.category.aop.common=debug,stdout log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender log4j.appender.dailyfile.File = C:\\nigth-spring\\logfile.log log4j.appender.dailyfile.Append = true log4j.appender.dailyfile.DatePattern='.'yyyy-MM-dd log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout log4j.appender.dailyfile.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n |
[결과]
find customer..90 null
insert customer...java
member delete...
WARN ({main} ParamCheckAspect.java[checkLogging]:19) [2013-04-25 20:29:59,476] - 잘못된 입자값 : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint findContent
findContent...
2
AOP-after-returning
BoardService.java
1 2 3 4 5 6 7 8 9 10 11 | package kosta.aop.board; public class BoardService { public void insertContent(){ System.out.println("board insertContent"); } public String selectContent(String no){ System.out.println("selectContent.."+no); return no+" selectContent"; } } |
MemberDao.java
1 2 3 4 5 6 7 | package kosta.aop.member; public class MemberDao { public String selectPass(){ return "selectPass"; } } |
MemberService.java
1 2 3 4 5 6 7 8 9 10 11 | package kosta.aop.member; public class MemberService { public int selectAge(){ return 11; } public String selectAddress(){ return "selectAddress 판교"; } } |
ParamCheckAspect.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package kosta.common; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; public class ParamCheckAspect { private Log log = LogFactory.getLog(getClass()); public void logging(JoinPoint point, Object retValue){ String cn = point.getTarget().getClass().getName(); String mn = point.getSignature().getName(); log.debug(cn+" "+mn+" 리턴값:"+retValue); } } |
TestAOP.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 | package test; import kosta.aop.board.BoardService; import kosta.aop.member.MemberDao; import kosta.aop.member.MemberService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestAOP { /** * 요구사항 * 공통 기능 정의 클래스 : kosta.common.LoggingAspect * logging(JoinPoint) * 공통기능 : log.debug(클래스명, 메서드명) * 적용대상 : kosta.aop 이하의 모든 팩키지의 * Service로 마치는 클래스의 * public 접근제어자의 * return타입이 String, * method명 select로 시작되고 * 매개변수는 관계없음 * 적용시점 : before -------> after-returning */ public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml"); BoardService bs = (BoardService) context.getBean("boardService"); MemberDao md = (MemberDao) context.getBean("memberDao"); MemberService ms = (MemberService) context.getBean("memberService"); bs.insertContent(); System.out.println(bs.selectContent("1")); System.out.println(md.selectPass()); System.out.println(ms.selectAddress()); System.out.println(ms.selectAddress()); System.out.println(ms.selectAge());; } } |
aop.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?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.xsd" > <bean id="boardService" class="kosta.aop.board.BoardService"></bean> <bean id="memberDao" class="kosta.aop.member.MemberDao"></bean> <bean id="memberService" class="kosta.aop.member.MemberService"></bean> <bean id="checkAspect" class="kosta.common.ParamCheckAspect"></bean> <aop:config> <aop:pointcut expression="execution(public String kosta.aop..*Service.select*(..))" id="checkPointCut"/> <aop:aspect ref="checkAspect"> <aop:after-returning method="logging" returning="retValue" pointcut-ref="checkPointCut"/> </aop:aspect> </aop:config> </beans> |
log4j.propertis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | log4j.rootLogger = warn,stdout log4j.additivity.kosta.common=false log4j.category.kosta.common=debug,stdout log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender log4j.appender.dailyfile.File = C:\\nigth-spring\\logfile.log log4j.appender.dailyfile.Append = true log4j.appender.dailyfile.DatePattern='.'yyyy-MM-dd log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout log4j.appender.dailyfile.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n |
[결과]
board insertContent
DEBUG ({main} ParamCheckAspect.java[logging]:12) [2013-04-25 20:37:22,301] - kosta.aop.board.BoardService selectContent
selectContent..1
1 selectContent
selectPass
DEBUG ({main} ParamCheckAspect.java[logging]:12) [2013-04-25 20:37:22,301] - kosta.aop.member.MemberService selectAddress
selectAddress 판교
DEBUG ({main} ParamCheckAspect.java[logging]:12) [2013-04-25 20:37:22,311] - kosta.aop.member.MemberService selectAddress
selectAddress 판교
11
AOP-after-throwing
BoardService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package kosta.aop.board; import kosta.aop.exception.MyException; public class BoardService { public void insertContent(){ System.out.println("board insertContent.."); } public String selectContent(String no){ System.out.println("selectContent exe.."); return no+" selectContent"; } public int getImg(String no) throws MyException{ if(no==null) throw new MyException("no가 null"); return 100; } } |
MyException.java
1 2 3 4 5 6 7 8 9 10 | package kosta.aop.exception; public class MyException extends Exception { public MyException(String message) { super(message); // TODO Auto-generated constructor stub } } |
MemberDao.java
1 2 3 4 5 6 7 | package kosta.aop.member; public class MemberDao { public String selectPass(){ return "selectPass"; } } |
MemberService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package kosta.aop.member; import kosta.aop.exception.MyException; public class MemberService { public int selectAge(){ return 11; } public String selectAddress(){ System.out.println("selectAddress....exe"); return "selectAddress 판교"; } public String getNick(String id) throws MyException{ String nick=null; if(id!=null){ nick="아이유"; }else{ throw new MyException("아이디가 null"); } return nick; } } |
LoggingAspect.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package kosta.common; import kosta.aop.exception.MyException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; public class LoggingAspect { private Log log = LogFactory.getLog(getClass()); public void exceptionLogging(JoinPoint point, MyException ex){ String cn = point.getTarget().getClass().getName(); String mn = point.getSignature().getName(); log.debug(cn+" "+mn+" 예외메세지:"+ex.getMessage()); } } |
Test.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 | package test; import kosta.aop.board.BoardService; import kosta.aop.exception.MyException; import kosta.aop.member.MemberDao; import kosta.aop.member.MemberService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test{ /** * 요구 사항 * 공통기능 정의 클래스 : kosta.common.LoggingAspect * logging(JoinPoint) * * 공통기능 : log.debug(클래스명, 메서드명); * 적용대상 : kosta.aop 이하의 모든 팩키지의 * Service로 마치는 클래스의 * public 접근제어자의 * 리턴타입 관계없이 * get 으로 시작되는 메서드의 * 인자값 관계없이 대상지정 * * 위 대상 메서드가 수행시에 MyException 이 * 발생 되는 경우 log.error(예외메세지); 를 남긴다. */ public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("aop.xml"); BoardService bs=(BoardService)context.getBean("boardService"); MemberDao md=(MemberDao)context.getBean("memberDao"); MemberService ms=(MemberService)context.getBean("memberService"); bs.insertContent(); System.out.println(bs.selectContent("1")); System.out.println(md.selectPass()); System.out.println(ms.selectAddress()); System.out.println(ms.selectAge()); try { System.out.println(bs.getImg(null)); } catch (MyException e) { System.out.println(e.getMessage()); } try { System.out.println(ms.getNick(null)); } catch (MyException e) { System.out.println(e.getMessage()); } } } |
aop.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 | <?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.xsd" > <bean id="boardService" class="kosta.aop.board.BoardService"></bean> <bean id="memberDao" class="kosta.aop.member.MemberDao"></bean> <bean id="memberService" class="kosta.aop.member.MemberService"></bean> <bean id="checkAspect" class="kosta.common.LoggingAspect"></bean> <!-- kosta.aop 이하의 모든 package의 Service로 마치는 클래스의 public 접근제어자의 리턴타입 관계없이 get으로 시작되는 메서드의 인자값 관계없이 대상 지정 --> <aop:config> <aop:pointcut expression="execution(public * kosta.aop..*Service.get*(..))" id="checkPointCut"/> <aop:aspect ref="checkAspect"> <aop:after-throwing method="exceptionLogging" throwing="ex" pointcut-ref="checkPointCut"/> </aop:aspect> </aop:config> </beans> |
log4j.propertis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | log4j.rootLogger = warn,stdout log4j.additivity.kosta.common=false log4j.category.kosta.common=debug,stdout log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender log4j.appender.dailyfile.File = C:\\nigth-spring\\logfile.log log4j.appender.dailyfile.Append = true log4j.appender.dailyfile.DatePattern='.'yyyy-MM-dd log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout log4j.appender.dailyfile.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] - %m%n |
[결과]
board insertContent..
selectContent exe..
1 selectContent
selectPass
selectAddress....exe
selectAddress 판교
11
DEBUG ({main} LoggingAspect.java[exceptionLogging]:15) [2013-04-25 22:03:47,237] - kosta.aop.board.BoardService getImg 예외메세지:no가 null
no가 null
DEBUG ({main} LoggingAspect.java[exceptionLogging]:15) [2013-04-25 22:03:47,237] - kosta.aop.member.MemberService getNick 예외메세지:아이디가 null
아이디가 null
AOP- after-throwing2
OrderAspect.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 | package shop.common; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import shop.data.WareHouse; import shop.exception.BookInventoryException; import shop.exception.FlowerInventoryException; public class OrderAspect { private Log log=LogFactory.getLog(getClass()); private WareHouse wareHouse; public OrderAspect(WareHouse wareHouse) { super(); this.wareHouse = wareHouse; } /** * 책 재고 부족시 log.info() 로 책 1권 출판사에 주문 꽃 재고 부족시 log.info() 로 꽃 5송이 화원에 주문 * @param point * @param ex */ public void order(JoinPoint point,Exception ex){ Object params[] = point.getArgs(); int count = (int)params[0]; String message = null; // instanceof 객체의 타입을 비교 if(ex instanceof FlowerInventoryException){ message="꽃"+(count-wareHouse.getFlowerCount())+"송이 화원에 주문"; }else if(ex instanceof BookInventoryException){ message="책"+(count-wareHouse.getFlowerCount())+"권 출판사에 주문"; } log.info(message); } } |
WareHouse.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package shop.data; // 제품 재고 수량 public class WareHouse { private int flowerCount=10; private int bookCount=10; public int getFlowerCount() { return flowerCount; } public void setFlowerCount(int flowerCount) { this.flowerCount = flowerCount; } public int getBookCount() { return bookCount; } public void setBookCount(int bookCount) { this.bookCount = bookCount; } } |
BookInventoryException.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package shop.exception; public class BookInventoryException extends Exception{ public BookInventoryException() { super(); // TODO Auto-generated constructor stub } public BookInventoryException(String message) { super(message); // TODO Auto-generated constructor stub } } |
FlowerInventoryException.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package shop.exception; public class FlowerInventoryException extends Exception { public FlowerInventoryException() { super(); // TODO Auto-generated constructor stub } public FlowerInventoryException(String message) { super(message); // TODO Auto-generated constructor stub } } |
BookService.java
1 2 3 4 5 6 7 8 9 10 11 | package shop.service; import shop.data.WareHouse; import shop.exception.BookInventoryException; public interface BookService { public void setWareHouse(WareHouse wareHouse); public void sellBook(int count) throws BookInventoryException; public void meeting(); } |
BookServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package shop.service; import shop.data.WareHouse; import shop.exception.BookInventoryException; public class BookServiceImpl implements BookService { private WareHouse wareHouse; @Override public void setWareHouse(WareHouse wareHouse) { this.wareHouse=wareHouse; } @Override public void sellBook(int count) throws BookInventoryException { if(wareHouse.getBookCount()<count){ throw new BookInventoryException("책 재고 부족"); } System.out.println("책 "+count+"권 판매"); } @Override public void meeting() { System.out.println("저자와의 대화.."); } } |
FlowerService.java
1 2 3 4 5 6 7 8 9 10 | package shop.service; import shop.data.WareHouse; import shop.exception.FlowerInventoryException; public interface FlowerService { public void setWareHouse(WareHouse wareHouse); public void sellFlower(int count) throws FlowerInventoryException; public void proposeEvent(); } |
FlowerServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package shop.service; import shop.data.WareHouse; import shop.exception.FlowerInventoryException; public class FlowerServiceImpl implements FlowerService { private WareHouse wareHouse; @Override public void setWareHouse(WareHouse wareHouse) { this.wareHouse=wareHouse; } @Override public void sellFlower(int count) throws FlowerInventoryException { if(count>wareHouse.getFlowerCount()){ throw new FlowerInventoryException("꽃 재고 부족!"); } System.out.println("꽃 "+count+"송이 판매"); } @Override public void proposeEvent(){ System.out.println("프로포즈 이벤트"); } } |
TestAOP.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 | package shop.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import shop.exception.BookInventoryException; import shop.exception.FlowerInventoryException; import shop.service.BookService; import shop.service.FlowerService; public class TestAOP { public static void main(String[] args) { ApplicationContext context=new ClassPathXmlApplicationContext("aop.xml"); BookService book=(BookService) context.getBean("book"); FlowerService flower=(FlowerService)context.getBean("flower"); book.meeting(); try { book.sellBook(11); } catch (BookInventoryException e) { System.out.println(e.getMessage()); } flower.proposeEvent(); try { flower.sellFlower(15); } catch (FlowerInventoryException e) { System.out.println(e.getMessage()); } } } |
aop.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 | <?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.xsd" > <bean id="wareHouse" class="shop.data.WareHouse"></bean> <bean id="book" class="shop.service.BookServiceImpl"> <property name="wareHouse"> <ref bean="wareHouse"/> </property> </bean> <bean id="flower" class="shop.service.FlowerServiceImpl"> <property name="wareHouse"> <ref bean="wareHouse"/> </property> </bean> <!-- 공통 관심사항을 정의한 빈 --> <bean id="orderAspect" class="shop.common.OrderAspect"> <constructor-arg> <ref bean="wareHouse"/> </constructor-arg> </bean> <aop:config> <aop:pointcut expression="execution(public * shop.service..*ServiceImpl.sell*(int))" id="checkPointCut"/> <aop:aspect ref="orderAspect"> <aop:after-throwing method="order" throwing="ex" pointcut-ref="checkPointCut"/> </aop:aspect> </aop:config> </beans> |
[결과]
저자와의 대화..
INFO ({main} OrderAspect.java[order]:38) [2013-04-25 22:09:27,052] - 책1권 출판사에 주문
책 재고 부족
프로포즈 이벤트
INFO ({main} OrderAspect.java[order]:38) [2013-04-25 22:09:27,062] - 꽃5송이 화원에 주문
꽃 재고 부족!
AOP
advice -> return
-> around (before, after-returning, after-throwing, returning을 한곳에서 처리)
5일차는 Exception 처리에 대한 간단한 설명으로 수업시작
'Framework > Spring' 카테고리의 다른 글
[Spring & ibatis] 수업 6일 (0) | 2013.04.29 |
---|---|
[Spring & ibatis] 수업 5일 (0) | 2013.04.26 |
[Spring & ibatis] 수업 3일 (0) | 2013.04.24 |
[Spring & ibatis] 수업 2일 (0) | 2013.04.23 |
[Spring & ibatis] 수업 1일 (0) | 2013.04.22 |