Spring 프레임워크의 이해 – day3 자바지기.

Slides:



Advertisements
Similar presentations
Transaction ㅇ Transaction 을 직접 구현하려면, 까다로운 설계와 복잡한 코드를 필요로 하고 수정에 공수가 많이 들게 된다. ㅇ 스프링에서 제공하는 Transaction Manager 를 사용하여 쉽고 간편하게 어려운 트랜잭션을 해결할 수 있다. xml.
Advertisements

Chapter 16 : Struts 프레임워크 2. chapter 16 : Struts 프레임워크 2.
Spring MVC ㅇ 스프링 MVC 구성요소 설명 DispatcherServlet 클라이언트의 요청을 컨트롤러에게 전달하고
10. 예외 처리.
컴퓨터 응용 및 실습 Part1. OOP&Java Programming data type Review
최신 소프트웨어 공학 개요 11.1 컴포넌트 기반 소프트웨어 개발 11.2 웹 엔지니어링 11.3 정형적 명세 기법
컴퓨터프로그래밍 1주차실습자료 Visual Studio 2005 사용법 익히기.
4강. Servlet 맛보기 Servlet 문서 작성 하기 web.xml에 서블릿 맵핑 어노테이션을 이용한 서블릿 맵핑
최윤정 Java 프로그래밍 클래스 상속 최윤정
Internet Computing KUT Youn-Hee Han
JPetStore 분석자료 1.0 Spring framework 작성자 : 김태완.
2 서블릿의 기초.
3장. 웹 어플리케이션과 JSP 및 Servlet의 이해 제3장.
9 표준 액션.
5 익셉션 처리.
MVC 기반 게시판 작성 Youbok Choi.
메소드 호출과 힙 원격 메소드 호출 서블릿 엔터프라이즈 자바 빈즈
4 쿠키와 세션.
1강 01장. 웹과 자바.
IOC, DI 2015 Web Service Computing.
AOP 개념 및 Spring의 AOP 기능.
4장. 웹로직 서버상에서의 JDBC와 JTA의 운용
Lesson 9. 예외처리.
컴퓨터응용과학부 Java Enterprize(DB) 제 13 주
Spring Framework & MyBatis
Struts2 를 이용한 SOCAS Homepage
2장 자바환경과 자바 프로그램 2.1 자바 개발 환경 2.2 자바 통합환경 2.3 자바 응용 프로그램과 애플릿 프로그램
10강. AOP(Aspect Oriented Programming)-II
9강. AOP(Aspect Oriented Programming)-I
AOP (Aspect Oriented Programming)
SqlParameter 클래스 선문 비트 18기 발표자 : 박성한.
소프트웨어 분석과 설계 Struts2 & JBOSS 설치하기
KHS JDBC Programming 4 KHS
웹 애플리케이션 로깅 및 오류 처리 기법 웹 애플리케이션 로깅의 필요성을 이해한다 로깅의 분류 및 구현 방안을 학습한다
ㅇ 스프링 설정파일 (dispatcher-servlet.xml)
11강. 스프링 MVC 기초 스프링 MVC 개요 스프링 MVC 구조 살펴보기 resources 폴더
3강. JSP 맛보기 JSP 문서 작성 하기 JSP 아키텍처 Lecturer Kim Myoung-Ho Nickname 블스
Web Socket.
컴퓨터응용과학부 Java Enterprize(DB) 제 7 주
AOP (Aspect Oriented Programing)
16강. 스프링MVC 게시판-I 프로젝트 설계 DataBase 구축 프로젝트 생성 Lecturer Kim Myoung-Ho
Cairngorm(캔곰) : Flex UI 프레임워크
Ch.1 Iterator Pattern <<interface>> Aggregate +iterator
개발 환경 세팅.
Spring 프레임워크의 이해 2. Spring Introduction.
3. Spring 프레임워크의 IoC 컨테이너 개념
Spring 프레임워크의 이해 1.Architecture.
Spring 프레임워크의 이해 – day1 자바지기.
Spring 프레임워크의 이해 3. Spring IoC 이해 및 활용.
MVC 모델을 이용한 웹 애플리케이션 작성 웹 애플리케이션 개발 순서를 알아본다 웹 애플리케이션의 실행 순서를 이해한다.
Lesson 2. 기본 데이터형.
객체지향의 한계를 넘어, AOP 전은영,이재훈 고덕윤.
SpringFramework 중간고사 요약 REST by SpringFramework.
컴퓨터공학실습(I) 3주 인공지능연구실.
Spring DI 이해 및 활용.
3장. 웹로직 서버에서의 서블릿과 JSP의 운용 3-1. 서블릿, JSP를 실행하기 전의 환경 설정
Internet Computing KUT Youn-Hee Han
자바 5.0 프로그래밍.
Chapter 08 : 서블릿 고급3. chapter 08 : 서블릿 고급3 학습목표 서블릿 속성과 Scope ServletContext HttpSession HttpServletRequest Filter API 요청 필터 응답 필터 url-pattern 8 가지.
Internet Computing KUT Youn-Hee Han
Spring Security 2015 Web Service Computing.
4. Spring 프레임워크의 AOP 개념.
Index.html example.xml test.action .class.java test.ibatis.
제 11 장 자바빈즈를 이용한 JDBC 프로그래밍 학기 인터넷비즈니스과 강 환수 교수.
.Net Web Application 2007 컴퓨터공학실험(Ⅰ)
Architecture.
Spring Introduction.
MIDP 네트워크 프로그래밍 ps lab 김윤경.
슬라이드 쇼의 설정 슬라이드 쇼의 실행 파일과 폴더의 관리 글꼴을 포함해서 저장 웹 페이지로 게시 압축 파일
Favorite List Management Service : 화면 설계
Presentation transcript:

Spring 프레임워크의 이해 – day3 자바지기

첫째 날 둘째 날 셋째 날 개발 환경 세팅 Spring 기본 Spring MVC 사용자 관리 시스템 개발 (실습) Spring DI Spring AOP Spring JDBC & Transaction Spring Test

모델 1

모델 2 - MVC

Controller(또는 Action) 사용자 입력 데이터 추출 입력 데이터에 대한 유효성 체크(Java Script를 이용할 경우 JSP(View)에서도 가능) 입력 데이터를 비즈니스 Layer로 전달하기 위한 변환 작업 비즈니스 Layer와 Interface 비즈니스 Layer에서 발생한 에러 처리 비즈니스 Layer에서 반환된 데이터를 View에 전달

모델 1 B R O W S E 1. Request JSP 2. Response

모델 2 B R O W S E (Controller) Servlet (View) JSP 1. Request 2. Response 3. Request (View) JSP 4. Response

데모 및 실습 모델 2 기반의 초간단 프레임워크 svn://www.javajigi.net/javajigi id : anonymous pwd : 없음 model2 프로젝트 checkout pom.xml 오른쪽 클릭 maven build.. eclipse:clean eclipse:eclipse를 통한 프로젝트 생성

Spring MVC

2 3 1 4 5 6 HandlerMapping 요청 DispatcherServlet Controller ModelAndView 1 4 5 ViewResolver 6 View

web.xml 설정 <servlet> <servlet-name>action</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <url-pattern>*.do</url-pattern> </servlet-mapping> <url-pattern>*.html</url-pattern>

=> 서블릿 이름-servlet.xml Spring 설정 파일 => 서블릿 이름-servlet.xml <servlet> <servlet-name>action</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> WEB-INF/action-servlet.xml

Controller

Controller Interface public interface Controller { ModelAndView handleRequest( HttpServletRequest request, HttpServletResponse response) throws Exception; }

HelloWorldController 실습 HelloWorldController public class HelloWorldController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { return new ModelAndView("hello", "message", "Hello World!! Welcome to Page!!"); } action-servlet.xml <bean id="helloController“ class="net.javajigi.web.HelloWorldController" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="urlMap"> <map> <entry key="/hello.do" value-ref="helloController"/> </map> </property> </bean>

2 3 1 4 5 6 SimpleUrlHandlerMapping “hello” /hello.do DispatcherServlet HelloWorldController ModelAndView 1 4 “hello”, “message” 5 InternalResourceViewResolver 6 /WEB-INF/jsp/hello.jsp

UrlFilenameViewController = No Model 데이터 정적인 페이지

org.springframework.web.servlet.mvc.UrlFilenameViewController 실습 org.springframework.web.servlet.mvc.UrlFilenameViewController action-servlet.xml <bean id="staticViewController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController" /> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="urlMap"> <map> <entry key="/**/*.html" value-ref="staticViewController"/> </map> </property> </bean>

MultiActionController DispatchAction of Struts = DispatchAction of Struts Action of Webwork

= 1 : 1 ListAction InsertAction UpdateAction ViewAction DeleteAction List.do B R O W S E ListAction Insert.do InsertAction Update.do UpdateAction View.do ViewAction Delete.do DeleteAction = 1 : 1 URL : Action

단점 URL이 추가될 때마다 Action(Controller)를 추가해야함. Action(Controller)가 추가될 때마다 설정 파일에 Action 정보 추가 하나의 URL이 추가될 때마다 추가되어야 하는 부분이 많아짐으로서 생산성 저하. Action(Controller)의 숫자가 많아질수록 유지보수의 어려움. 너무도 복잡한 설정 파일로 인해 유지보수의 어려움.

= N : 1 SampleAction URL : Action B R O W S E List.do Insert.do Update.do View.do Delete.do = N : 1 URL : Action

실습 - MultiActionController UserController public class UserController extends MultiActionController { public ModelAndView list(HttpServletRequest request, HttpServletResponse response) throws Exception { List<User> userList = userService.findUserList(); ModelAndView mav = new ModelAndView(); mav.addObject("users", userList); return mav; } public ModelAndView edit(HttpServletRequest request, HttpServletResponse response) User user = new User(); bind(request, user); userService.updateUser(user); return new ModelAndView("redirect:/user/list.do");

URL Mapping : InternalPathMethodNameResolver 설정 파일에 아무 것도 설정되어 있지 않을 경우 InternalPathMethodNameResolver가 Default URL에 포함되어 있는 Method 이름을 실행한다. http://localhost:8080/user/edit.do => UserController의 edit() 메써드 호출 일반적으로 가장 많이 사용한다.

URL Mapping : ParameterMethodNameResolver action-servlet.xml <property name="methodNameResolver"> <bean class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"> <property name="paramName" value="method"/> </bean> </property> URL을 통하여 전달되는 인자 이름을 통하여 실행하는 메써드 결정 http://localhost:8080/user.do?method=edit => UserController의 edit() 메써드 호출

URL Mapping : PropertiesMethodNameResolver action-servlet.xml <bean id="propsResolver" class="org....mvc.multiaction.PropertiesMethodNameResolver"> <property name="mappings"> <value> /user/modify.do=edit /user/list.do=list /user/remove.do=delete </value> </property> </bean> 요청 URL과 실행 메써드를 Mapping한다. Properties 파일을 통하여 관리하는 것도 가능하다. http://localhost:8080/user/modify.do => UserController의 edit() 메써드 호출

기존 방식

SimpleFormController

데모 사용자, 게시물 관리 svn://www.javajigi.net/javajigi id : anonymous pwd : 없음 sfw07 프로젝트 checkout pom.xml 오른쪽 클릭 maven build.. eclipse:clean eclipse:eclipse를 통한 프로젝트 생성

Spring MVC의 Interceptor public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) void afterCompletion( Exception ex) }

실습 - SignonInterceptor public class SignonInterceptor extends HandlerInterceptorAdapter { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { User userSession = (User) WebUtils.getSessionAttribute(request, "user"); if (userSession == null) { String url = request.getServletPath(); String query = request.getQueryString(); ModelAndView modelAndView = new ModelAndView("redirect:/signon/login.html"); if (query != null) { modelAndView.addObject("signonForwardAction", url+"?"+query); } else { modelAndView.addObject("signonForwardAction", url); throw new ModelAndViewDefiningException(modelAndView); return true;

실습 - SignonInterceptor action-servlet.xml <bean id="signonInterceptor" class="net.javajigi.user.web.SignonInterceptor"/> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="signonInterceptor"/> </list> </property> <property name="urlMap"> <map> <entry key="/user/*.do" value-ref="userController"/> <entry key="/signon/logout.do" value-ref="signonController"/> </map> </bean>

HandlerMapping

BeanNameUrlHandlerMapping <bean name="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <bean name="/menu.do" class="net.javajigi.common.web.MenuController" /> <bean name="/changelocale.do" class="net.javajigi.common.web.SessionLocaleController" /> URL과 Controller 설정을 한 곳에서 할 수 있다. 다양한 Interceptor 설정을 하는 것이 힘들다.

SimpleUrlHandlerMapping <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="urlMap"> <map> <entry key="/**/*.html" value-ref="staticViewController"/> <entry key="/user/addForm.do" value-ref="userController"/> <entry key="/user/add.do" value-ref="userController"/> <entry key="/signon/login.do" value-ref="signonController"/> <entry key="/hello.do" value-ref="helloController"/> </map> </property> </bean> 다양한 Interceptor 설정을 하는 것이 가능하다. URL 설정과 Controller 설정이 분리되어 있다.

ControllerClassNameHandlerMapping <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" /> <bean id="viewNameTranslator" class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator" /> HelloWorldController => helloworld.do HelloWorldController.hello => helloworld/hello.do

DefaultAnnotationHandlerMapping <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <context:component-scan base-package="net.javajigi"/> @Controller public class UserController { @RequestMapping("/user/list.do") public ModelMap listHandler() { List<User> userList = userService.findUserList(); return new ModelMap("users", userList); }

여러 개의 HandlerMapping 사용 <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" p:order="1"> <property name="urlMap"> <map> <entry key="/**/*.html"> <ref local="staticViewController" /> </entry> </map> </property> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="2"/> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" p:order="3" />

ViewResolver

ViewResolver

InternalResourceViewResolver <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>

VelocityViewResolver <bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> <property name="resourceLoaderPath"> <value>/WEB-INF/vm/</value> </property> <property name="velocityProperties"> <props> <prop key="input.encoding">utf-8</prop> <prop key="output.encoding">utf-8</prop> <prop key="file.resource.loader.cache">false</prop> </props> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver"> <property name="requestContextAttribute" value="rc" /> <property name="cache" value="false" /> <property name="suffix" value=".vm" /> <property name="contentType"> <value>text/html; charset=utf-8</value>

XmlViewResolver views.xml <bean class="org.springframework.web.servlet.view.XmlViewResolver" p:location="/WEB-INF/views.xml" /> views.xml <?xml version="1.0" encoding="UTF-8"?> <beans ...> <bean name="xmlView" class="net.javajigi.user.web.coc.XMLUserView" /> <bean name="excelView" class="net.javajigi.user.web.coc.ExcelUserView" /> </beans>

ResourceBundleViewResolver <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" p:basename="views" /> views.properties xmlView.class=net.javajigi.user.web.coc.XMLUserView excelView.class=net.javajigi.user.web.coc.ExcelUserView

여러 개의 ViewResolver 사용하기 <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" p:basename="views" p:order="1"/> <bean class="org.springframework.web.servlet.view.XmlViewResolver" p:location="/WEB-INF/views.xml" p:order="2"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="3"/>

redirect or forward return new ModelAndView("redirect:/user/list.do"); return new ModelAndView(“forward:/user/list.do");

View

실습 XMLUserView.java views.properties public class XMLUserView extends AbstractView { protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { List<User> users = (List<User>)model.get("users"); StringBuffer sb = new StringBuffer(); sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); .... response.setContentType("text/xml;charset=utf-8"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write(sb.toString()); } views.properties xmlView.class=net.javajigi.user.web.coc.XMLUserView

실습 ExcelUserView.java views.properties public class ExcelUserView extends AbstractJExcelView { protected void buildExcelDocument(Map model, WritableWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception { List<User> users = (List<User>)model.get("users"); WritableSheet sheet = workbook.createSheet("User List", workbook.getNumberOfSheets()); sheet.addCell(new Label(0, 0, "User ID")); sheet.addCell(new Label(1, 0, "Name")); sheet.addCell(new Label(2, 0, "Email")); for (int i=0; i < users.size(); i++) { User user = (User) users.get(i); sheet.addCell(new Label(0, i+1, user.getUserId())); sheet.addCell(new Label(1, i+1, user.getName())); sheet.addCell(new Label(2, i+1, user.getEmail())); } views.properties excelView.class=net.javajigi.user.web.coc.ExcelUserView

Locale Resolver

AcceptHeaderLocaleResolver : Default <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"/>

CookieLocaleResolver <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <property name="cookieName" value="clientlanguage"/> <property name="cookieMaxAge" value="100000"> </bean>

SessionLocaleResolver <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

LocaleChangeInterceptor <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" /> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="siteLanguage"/> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="interceptors"> <list> <ref bean="localeChangeInterceptor"/> <ref bean="signonInterceptor"/> </list> </property> .... </bean>

ThemeResolver

ResourceBundleThemeSource theme.properties gobal.css=/css/global.css user.css=/css/user.css list.jsp <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <html> <head> <link rel=stylesheet href="<spring:theme code="gobal.css"/>" type="text/css"> <link rel=stylesheet href="<spring:theme code="user.css"/>" type="text/css"> </head> <body> ... </body> </html>

ThemeResolver action-servlet.xml <bean id="themesource" class="org.springframework.ui.context.support.ResourceBundleThemeSource"/> <bean id="themeResolver" class="org.springframework.web.servlet.theme.SessionThemeResolver" p:defaultThemeName="theme"/>

ExceptionResolver

dataAccessFailure => 논리적인 View 이름 SimpleMappingExceptionResolver <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop> <prop key="org.springframework.transaction.TransactionException">dataAccessFailure</prop> </props> </property> </bean> dataAccessFailure => 논리적인 View 이름

MultipartResolver

데모 게시판 파일 업로드 svn://www.javajigi.net/javajigi id : anonymous pwd : 없음 sfw07 프로젝트 checkout pom.xml 오른쪽 클릭 maven build.. eclipse:clean eclipse:eclipse를 통한 프로젝트 생성

첫째 날 둘째 날 셋째 날 개발 환경 세팅 Spring 기본 Spring MVC 사용자 관리 시스템 개발 (실습) Spring DI Spring AOP Spring JDBC & Transaction Spring Test

절차적 프로그래밍 OOP AOP

다음 문제의 정답은? 1 11 12 1121 122111 112213 ???????

사고의 전환

요구사항!! MessageRenderer, MessageProvider의 모든 메써드 시작과 종료시 “MethodName 시작”, “MethodName 종료”라는 Logging 메시지를 출력한다.

요구사항 변경!! MessageRenderer, MessageProvider의 모든 메써드 시작과 종료시 “MethodName Start”, “MethodName End”라는 Logging 메시지를 출력한다.

요구사항 변경!! 메써드로 전달되는 인자를 Logging 메시지로 출력한다. MessageRenderer, MessageProvider의 모든 메써드 시작과 종료시 “MethodName Start”, “MethodName End”라는 Logging 메시지를 출력한다. 메써드로 전달되는 인자를 Logging 메시지로 출력한다.

삽질의 연속

실습 요구사항!! DAO 클래스의 메써드 실행속도가 500ms이 넘을 경우 Warning 메시지를 출력한다.

실습 - ProfilingAspect @Aspect public class ProfilingAspect { private static Log log = LogFactory.getLog(LoggingAspect25.class); @Pointcut("execution(* net.javajigi..dao..*(..))") public void daoPointcut() { } @Around ("net.javajigi.aop.ProfilingAspect.daoPointcut()") public Object profiling(ProceedingJoinPoint pjp) throws Throwable { StopWatch stopWatch = new StopWatch(); stopWatch.start("Dao Profiling"); Object returnValue = pjp.proceed(); stopWatch.stop(); if( stopWatch.getLastTaskTimeMillis() > 500 ) { if (log.isWarnEnabled()) { String targetClassName = pjp.getTarget().getClass().getName(); String targetMethodName = pjp.getSignature().getName(); log.warn(targetClassName + "." + targetMethodName + " execute : "); log.warn(stopWatch.prettyPrint()); return returnValue;

실습 – applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans ....> <aop:aspectj-autoproxy /> <bean id="profilingAspect" class="net.javajigi.aop.ProfilingAspect"/> </beans>

Join point 프로그램이 실행되는 중 식별할 수 있는 Point. 예를 들어 메써드의 실행, Exception Handling 등이 포함된다.

Advice Join Point에서 Aspect에 의하여 실행되는 Action을 의미 예를 들어 Profiling Aspect일 경우 Join Point에서 Profiling 하는 것을 의미한다.

Pointcut Join Point들을 선택하는 규칙을 정의하는 것. Weaving Rule을 정의하는 것

Target Object 애플리케이션의 핵심 비즈니스 로직을 구현하고 있는 Object Aspect에 의하여 Advice가 적용되는 Object

Aspect 하나의 Crosscutting Concern을 Aspect로 정의 가능 Advice와 Pointcut이 결합되어 Aspect가 된다. 예를 들어 Transaction, Security등이 하나의 Aspect가 된다.

Weaving Advcie, Pointcut, Target Object로 분리된 것을 하나로 결합하는 것을 의미 Weaving 작업을 지원하는 Tool(AspectJ, Spring AOP)을 Weaver라 지칭

Advice

Advice 의 종류 Before advice : Join Point 전에 실행되는 Advice. Around advice : Join Point 전, 후에 실행되는 Advice. After returning advice : Joint Point 완료된 후에 실행되는 Advice After throwing advice : Exception Throwing이 될 때 실행되는 Advice After (finally) advice : After returning advice, After throwing advice 모든 경우에 실행

Before Advice applicationContext.xml public void beforeLog(JoinPoint pjp) throws Throwable { String targetClassName = pjp.getTarget().getClass().getName(); String targetMethodName = pjp.getSignature().getName(); if (log.isDebugEnabled()) { log.debug(targetClassName + "." + targetMethodName + " 시작!"); Object[] args = pjp.getArgs(); for (int i = 0; i < args.length; i++) { log.debug("arg[" + i + "] : " + args[i]); } applicationContext.xml <beans> <bean id="loggingAdvice" class="net.javajigi.aop.LoggingAdvice25"/> <aop:config> <aop:aspect id="loggingAspect" ref="loggingAdvice"> <aop:pointcut id="logPointcut" expression="execution(* net.javajigi.di..*(..))"/> <aop:before pointcut-ref="logPointcut" method="beforeLog"/> </aop:aspect> </aop:config> </beans>

Around Advice applicationContext.xml public Object logOperations(ProceedingJoinPoint pjp) throws Throwable { String targetClassName = pjp.getTarget().getClass().getName(); String targetMethodName = pjp.getSignature().getName(); if (log.isDebugEnabled()) { log.debug(targetClassName + "." + targetMethodName + " 시작!"); Object[] args = pjp.getArgs(); for (int i = 0; i < args.length; i++) { log.debug("arg[" + i + "] : " + args[i]); } Object returnValue = pjp.proceed(); log.debug(targetClassName + "." + targetMethodName + " 종료!"); return returnValue; applicationContext.xml <beans> <bean id="loggingAdvice" class="net.javajigi.aop.LoggingAdvice25"/> <aop:config> <aop:aspect id="loggingAspect" ref="loggingAdvice"> <aop:pointcut id="logPointcut" expression="execution(* net.javajigi.di..*(..))"/> <aop:around pointcut-ref="logPointcut" method="logOperations"/> </aop:aspect> </aop:config> </beans>

After Returing Advice applicationContext.xml public void afterReturningLog(JoinPoint pjp, Object returnValue) throws Throwable { String targetClassName = pjp.getTarget().getClass().getName(); String targetMethodName = pjp.getSignature().getName(); if (log.isDebugEnabled()) { log.debug("Return Value : " + returnValue); log.debug(targetClassName + "." + targetMethodName + " 종료!"); } applicationContext.xml <beans> <bean id="loggingAdvice" class="net.javajigi.aop.LoggingAdvice25"/> <aop:config> <aop:aspect id="loggingAspect" ref="loggingAdvice"> <aop:pointcut id="logPointcut" expression="execution(* net.javajigi.di..*(..))"/> <aop:after-returning pointcut-ref="logPointcut" method="afterReturningLog" returning="returnValue"/> </aop:aspect> </aop:config> </beans>

After Throwing Advice applicationContext.xml public void afterThrowingLog(JoinPoint pjp, Throwable ex) throws Throwable{ String targetClassName = pjp.getTarget().getClass().getName(); String targetMethodName = pjp.getSignature().getName(); if (log.isDebugEnabled()) { log.debug(targetClassName + "." + targetMethodName + " Exception !"); log.debug("Exception Message : " + ex.getMessage()); } applicationContext.xml <beans> <bean id="loggingAdvice" class="net.javajigi.aop.LoggingAdvice25"/> <aop:config> <aop:aspect id="loggingAspect" ref="loggingAdvice"> <aop:pointcut id="logPointcut" expression="execution(* net.javajigi.di..*(..))"/> <aop:after-throwing pointcut-ref="logPointcut" method="afterThrowingLog" throwing="ex"/> </aop:aspect> </aop:config> </beans>

After Advice applicationContext.xml public void after(JoinPoint pjp) throws Throwable{ String targetClassName = pjp.getTarget().getClass().getName(); String targetMethodName = pjp.getSignature().getName(); if (log.isDebugEnabled()) { log.debug(targetClassName + "." + targetMethodName + " 종료!"); } applicationContext.xml <beans> <bean id="loggingAdvice" class="net.javajigi.aop.LoggingAdvice25"/> <aop:config> <aop:aspect id="loggingAspect" ref="loggingAdvice"> <aop:pointcut id="logPointcut" expression="execution(* net.javajigi.di..*(..))"/> <aop:after pointcut-ref="logPointcut" method="after"/> </aop:aspect> </aop:config> </beans>

Pointcut

Pointcut의 종류 – Spring 1.x StaticMethodMatcherPointcut DynamicMethodMatcherPointcut Perl5RegexpMethodPointcut JdkRegexpMethodPointcut NameMatchMethodPointcut ComposablePointcut ControlFlowPointcut

Pointcut의 종류 – Spring 2.x execution within this target args

Pointcut의 종류 – Spring 2.x @target @args @within @annotation bean(id or bean name) &&, ||, !

Pointcut의 예제 – Spring 2.x execution(* com.xyz.service.AccountService.*(..)) within(com.xyz.service.*) this(com.xyz.service.AccountService) @target(org.springframework.transaction.annotation.Transactional) @within(org.springframework.transaction.annotation.Transactional) @args(com.xyz.security.Classified) bean(*Service)

데모 – AOP를 이용한 권한 관리 @Permission(value = PermissionType.ADMINISTRATOR) public int removeUser(String userId) { int result = userDao.delete(userId); if (logger.isDebugEnabled()) { logger.debug("Removed " + userId + " in User System!!"); } return result; <aop:config> <aop:pointcut id="securityOperation" expression="execution(* net.javajigi..service..*(..)) and @annotation(permission)" /> <aop:aspect ref="securityAdvice"> <aop:before pointcut-ref="securityOperation" method="checkPermission" /> </aop:aspect> </aop:config> <bean id="securityAdvice" class="net.javajigi.security.PermissionAdvice" />

데모 – AOP를 이용한 권한 관리 public class PermissionAdvice { private static Log log = LogFactory.getLog(PermissionAdvice.class); public void checkPermission(Permission permission) throws PermissionException { PermissionType type = permission.value(); if (log.isDebugEnabled()) { log.debug("Permission Value : " + type); } if (type == PermissionType.ADMINISTRATOR ) { User user = UserContext.getUser(); if (!user.isAdmin()) { throw new PermissionException(user.getUserId());

Thank you.