@ModelAttribute 를 이용하면 2가지 작업이 가능

ㄱ. @RequestMapping 어노테이션이 적용되지 않은 별도 메소드로 모델에 추가될 객체를 생성가능
ㄴ. 커맨드 객체의 초기화 작업을 수행

두개의 RequestMapping 된 메소드가 같은 내용의 모델을 필요로 한다고 할때, 보통 그냥 별도의 메소드로 빼서 그것을 참조하게
한다. 

단 이렇게 하면 공통 메소드에 추가 조건절이 들어갈 수 도 있고 리턴에 대해서도 사용하는 측에서 맞춰야한다.

이때 @ModelAttribute를 사용할 수 있다.

 @ModelAttribute 를 메소드에 적용하면 해당 메소드가 생성한 객체가 뷰에 전달된다!!!!


아하.. 그래서 return 에 없는 객체들을 jsp 에서 참조가능했구나!!!!!!

즉 이 어노테이션은 ModelAttribute , 모델속성!! 이라는 의미의 단어를 그대로 뜻하는 것이다!!! 


@Controller
public class GameSearchController {
@Autowired
private SearchService searchService;

@ModelAttribute("searchTypeList")
public List<SearchType> referenceSearchTypeList() {
List<SearchType> options = new ArrayList<SearchType>();
options.add(new SearchType(1, "전체"));
options.add(new SearchType(2, "아이템"));
options.add(new SearchType(3, "캐릭터"));
return options;
}

@ModelAttribute("popularQueryList")
public String[] getPopularQueryList() {
return new String[] { "게임", "창천2", "위메이드" };
}

@RequestMapping("/search/main.do")
public String main() {
return "search/main";
}

@RequestMapping("/search/game.do")
public ModelAndView search(@ModelAttribute("command") SearchCommand command) {
ModelAndView mav = new ModelAndView("search/game");
System.out.println("검색어 = " + command.getQuery().toUpperCase());
SearchResult result = searchService.search(command);
mav.addObject("searchResult", result);
return mav;
}


해서 위의 콘트롤러를 보면 리턴해줄 모델의 값은 단지 mav일뿐이다. 허나 @ModelAttribute 어노테이션을 다른 메소드에 붙이므로써
모델에 속성을 추가하게 되는것이다!



다른 용도는 커맨드 객체 초기화 부분이다.
@ModelAttribute 어노테이션을 사용하면, 커맨드 객체의 초기화 작업을 수행할 수도 있다.
그럴수 밖에... 
@Controller
@RequestMapping("/account/create.do")
public class CreateAccountController {

@ModelAttribute("command")
public MemberInfo formBacking(HttpServletRequest request) {
if (request.getMethod().equalsIgnoreCase("GET")) {
MemberInfo mi = new MemberInfo();
Address address = new Address();
address.setZipcode(autoDetectZipcode(request.getRemoteAddr()));
mi.setAddress(address);
return mi;
} else {
return new MemberInfo();
}
}

private String autoDetectZipcode(String remoteAddr) {
return "000000";
}

@RequestMapping(method = RequestMethod.GET)
public String form() {
return "account/creationForm";
}

@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") MemberInfo memberInfo,
BindingResult result) {
new MemberInfoValidator().validate(memberInfo, result);
if (result.hasErrors()) {
return "account/creationForm";
}
return "account/created";
}
}

GET/POST 각각의 요청에 따라 객체 초기화가 가능하다.
위에서보면 submit 시의 command 가 바로 @ModelAttribute("command") 의 객체를 가르키게 된다.
왜냐면 @ModelAttribute 어노테이션이 적용된 메소드가 @RequestMapping 어노테이션이 적용된 메소드보다 먼저 호출되므로,
초기화 작업처럼 되는것이다.

그리고 ModelAttribute 어노테이션이 적용된 메소드는 RequestMapping 어노테이션이 적용된 메소드와 동일한 타입의 파라미터를 가질 수 있다.
 @ModelAttribute("command")
public MemberInfo formBacking(HttpServletRequest request) {

HttpServletRequest 말고도 Locale, @RequestParam 어노테이션 적용, @PathVariable 어노테이션등을 적용가능하다. 
 



'IT > 스프링' 카테고리의 다른 글

PathVariable 어노테이션을 이용한 URI 템플릿...  (0) 2012.01.16
URI 매칭.. (서블릿 맵핑)  (0) 2012.01.13
모델 생성.... (Model )  (0) 2012.01.13
@Controller 어노테이션... - 1 -  (0) 2012.01.10
filter....  (0) 2012.01.10
@RequestMapping 어노테이션이 적용된 메소드의 파라미터나 리턴타입으로 ModelAndView, Model, ModelMap, Map, 커맨드 객체 등을 이용해서 모델을 뷰에 전달하게 된다.

컨트롤러가 모델을 어떻게 뷰에 전달하는 지 살펴보도록 하자.

1.1 뷰에 전달되는 모델 데이터

        @RequestMapping("/search/game.do")
public ModelAndView search(@ModelAttribute("command") SearchCommand command, ModelMap model) {
                String[] queryList = getPopularQueryList();
                model.addAttribute("popularQueryList", queryList);
                 
ModelAndView mav = new ModelAndView("search/game");
SearchResult result = searchService.search(command);
mav.addObject("searchResult", result);
return mav;
}
 
근데 이상하다... model 자체를 리턴하지 않는데도 이게 뷰까지 간단 말야..
그리고 mav 도 별도로 또 가고 -ㅅ- 뭐야 이거

-->
 @ModelAttribute 를 메소드에 적용하면 해당 메소드가 생성한 객체가 뷰에 전달된다!!!!
아하.. 그래서 return 에 없는 객체들을 jsp 에서 참조가능했구나!!!!!!



즉.. JSP 에서 호출할때
${searchResult}, ${command.query} , ${popularQueryList} 로 접근된다.... ;;


1.2 Map, Model, ModelMap 을 통한 모델설정.. 

모델의 메소드에 대해서 잠깐 언급하자면,
Model, ModelMap 의 경우는 addAttribute 로 값을 설정하고, Map 이야.. put
그리고 Model은 인터페이스이다.   ExtendedModelMap 으로 할당해서 보통 쓴다.

1.3 ModelAndView 
 ModelAndView야 .. 뭐
    -setViewName() 을 통한 뷰 이름 설정
    -addObject(xxx,xxx) 를 이용한 전달값 추가
    -ModelAndView(뷰이름,맵) 생성자를 통한 뷰이름,Map 데이터 전달 






















 




'IT > 스프링' 카테고리의 다른 글

URI 매칭.. (서블릿 맵핑)  (0) 2012.01.13
@ModelAttribute  (2) 2012.01.13
@Controller 어노테이션... - 1 -  (0) 2012.01.10
filter....  (0) 2012.01.10
DispatcherServlet... more  (0) 2012.01.10


3.0 에서는 Controller 어노테이션을 이용해서 컨트롤러 클래스를 구현한단다. (과거에는 AbstractController 등을 썼음)

1. 기본구현
@Controller , @RequestMapping 어노테이션을 이용하면된다.

@Controller
public class HelloController {
@RequestMapping("/hello.do")
public String hello() {
            return "hello";
        }

@RequestMapping 어노테이션의 값에는 해당 메소드에서 처리할 URI가 무엇인지를 정의한다.
위의 경우 리턴값이 ModelAndView 가 아니라 String인데 이는 바로 이값이 ViewName이 된다.
이 뷰이름으로 ViewResolver 를 통해서 실제 view 파일을 가져와서 보여주겠지..


2. 전송방식... GET/POST
어차피... 이건 웹 어플리케이션이다. 전송하는 방식은 GET/POST 겠지.
같은 URL 이고 get/ post 의 다른 방식의 전송을 할때 다르게 처리가능하다.

@Controller
public class NewArticleController {
 
@RequestMapping(value="/article/newArticle.do", method = RequestMethod.GET)
public String form() {
return "article/newArticleForm";
}

@RequestMapping(value="/article/newArticle.do", method = RequestMethod.POST)
public String submit(@ModelAttribute("command") NewArticleCommand command) {
return "article/newArticleSubmitted";
}

public void setArticleService(ArticleService articleService) {
this.articleService = articleService;
}

}

만약 위처럼 처리하는 메소드가 동일한 URI에 대해서 처리하는것이라면 기본 URI를 지정할 수 도 있다.

@Controller
@RequestMapping("/article/newArticle.do")
public class NewArticleController {
 
@RequestMapping(method = RequestMethod.GET)
public String form() {
...
}

@RequestMapping(method = RequestMethod.POST)
public String submit(@ModelAttribute("command") NewArticleCommand command) {
...
}
...
}

만약 RequestMapping 어노테이션에 method 설정은 안하면 ,GET/POST 등 모든 HTTP 전송방식을 처리한다.



RequestMapping 에 대한 어노테이션 기능은 별도의 문서에 정리했다. 참고바란다.

3. 컨트롤러 메소드의 리턴타입?

매핑된 컨트롤러의 메소드가 해야할 일을 처리한다음... 뭔가를 리턴할것이다.
그 타입에 대한 설명이다.
@RequestMapping 메소드의 리턴타입
리턴타입 설명
ModelAndView 뷰 정보 및 모델정보를 담고 있는 ModelAndView 객체
Model 뷰에 전달할 객체 정보를 담고 있는 Model을 리턴한다. 이때 뷰 이름은 요청 URL로부터 결정된다.(RequestToViewNameTranslator 를 통해 뷰 결정)
 Map 뷰에 전달할 객체 정보를 담고 있는 Model을 리턴한다. 이때 뷰 이름은 요청 URL로부터 결정된다.(RequestToViewNameTranslator 를 통해 뷰 결정)
 String 뷰 이름을 리턴한다.
 View 객체View 객체를 직접 리턴, 해당 View 객체를 이용해서 뷰를 생성한다. 
 void메소드가 ServletResponse나, HttpServletResponse 타입의 파라미터를 갖는 경우 메소드가 직접 응답을 처리한다고 가정한다. 그렇지 않을 경우 요청 URL로 부터 결정된 뷰를 보여준다.(RequestToViewNameTranslator를 통해 뷰 결정) 
 @ResponseBody 어노테이션적용
메소드에서 @ResponseBody 어노테이션이 적용된 경우, 리턴객체를 HTTP응답으로 전송한다. HttpMessageConverter를 이용해서 객체를 HTTP 응답 스트림으로 변환한다. 


4. 컨트롤러 클래스 자동스캔
@Controller 어노테이션은 @Component 어노테이션과 마찬가지로 컴포넌트 스캔대상이다. 
<context:component-scan> 태그를 이용해서 아래처럼 선언해서 (xml) 어노테이션이 적용된 컨트롤러를 자동으로 로딩할 수 있다.

<context:component-scan base-package="madvirus.spring.chap06.controller" />


 



'IT > 스프링' 카테고리의 다른 글

@ModelAttribute  (2) 2012.01.13
모델 생성.... (Model )  (0) 2012.01.13
filter....  (0) 2012.01.10
DispatcherServlet... more  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10


스프링은 요청 파라미터의 캐릭터 인코딩을 설정할 수 있는 필터클래스인 CharacterEncodingFilter 클래스를 제공한단다...

         <filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>  // encoding을 통해서 지정
<param-value>EUC-KR</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>











'IT > 스프링' 카테고리의 다른 글

모델 생성.... (Model )  (0) 2012.01.13
@Controller 어노테이션... - 1 -  (0) 2012.01.10
DispatcherServlet... more  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09



최범균님의 스프링과 인터넷검색을 기반으로 제가 볼 용도의 글을 쓰는것입니다.

우선 web.xml에 dispatcherServlet 이름을 지정하여 생성하는데, 그러면 [dispatcherServlet이름]-servlet.xml 이 설정파일이 된다.

이때 servlet.xml 에 무식하게 다 적는 방법이 아닌 다른 설정을 불러와서 추가 하고 싶은경우가 있다면?

DispatcherServlet을 설정할때, contextConfingLocation 초기화 파라미터에 설정파일 목록을 지정하면된다. 
구분자는  콤마(,) 공백 , 탭, 줄바꿈(\n) , 세미콜론(;) 가 가능하다.

        <servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                <init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB--INF/main.xml /WEB-INF/bbs.xml</param-value>
</init-param> 
 
</servlet>

요런식으로 가능하게 된다.

혹은 dispatcherServlet 자체를 여러개 만들어도 된다.
 
        <servlet>
<servlet-name>front</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                <init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB--INF/front.xml</param-value>
</init-param> 
</servlet>
        <servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                <init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/rest.xml</param-value>
</init-param> 
</servlet>

그럼 front-serlvet.xml 과 rest-servlet.xml 2개의 설정파일이 생기게 되는데, 이때 같은빈을 각각의 설정파일에서 등록하고 있다면?
이를 공통화할 수 있다.
공통으로 사용될 빈 객체 정보를 담고 있는 설정파일목록을 아래처럼 service에 넣어서 처리가능하다.

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
        /WEB-INF/service.xml
    </param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 
        <servlet>
<servlet-name>front</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
        <servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>

ContextLoaderListener 가 생성하는 WebApplicationContext 는 웹어플리케이션에서 루트컨텍스트, DispatcherServlet이 생성하는 WebApplicationContext는 루트 컨텍스트를 부모로 사용하는 자식 컨텍스트가 된다. 자식은 root가 제공하는 빈을 쓸 수 있으므로 ContextLoaderListener 를 이용하여 설정하는것임

ContextLoaderListener 는 contextConfigLocation 컨텍스트 파라미터를 명시하지 않으면 /WEB-INF/applicationContext.xml 을 설정 파일로 사용한다.

<param-value> classpath:xxx.xml</param-value>
하면 클래스패스에 위치한 파일로부터 설정 정보를 읽어온다.

 
 

 



'IT > 스프링' 카테고리의 다른 글

@Controller 어노테이션... - 1 -  (0) 2012.01.10
filter....  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09
weaving??  (0) 2012.01.09


최범균님의 스프링과 인터넷검색을 기반으로 제가 볼 용도의 글을 쓰는것입니다.



흐음.. 이게 벌써 몇번째 정리인지 모르겠다.

아무튼 스프링책을 다시 보면서 정리하는 중이니 역시 정리하겠다. 스프링 또한 여차 프레임웍처럼 스프링 MVC를 제공한다.

간단하게 정리하자면.. 이 모든것을 총괄하는 커맨드센터격는 DispatcherServlet 이다.

1. 기본흐름

클라이언트 ---- 요청 ----> DispatcherServlet 

DispatcherServlet ---- 처리할 컨트롤러 파악 ----> HandlerMapping
DispatcherServlet <---- 처리할 컨트롤러 파악 ---- HandlerMapping

DispatcherServlet ---- 처리요청 ----> Controller 
DispatcherServlet <---- ModelAndView 리턴 ---- Controller
DispatcherServlet ---- ModelAndView 결과를 보여줄 View 파악 ----> ViewResolver
DispatcherServlet <---- View 리턴 ---- ViewResolver
DispatcherServlet ---- 결과물 출력요청 ----> View


개발자는 컨트롤러와 클라이언트의 응답결과화면 보여줄 뷰화면을 만드는게 주이다.
보통은 DispatcherServlet , HandlerMapping, ViewResolver 는 기본 클래스를 쓴다.


하여
ㄱ. DispatcherServlet을 web.xml파일에 설정한다.
ㄴ. 컨트롤러를 작성한다.
ㄷ. ViewResolver를 설정한다. 이는 컨트롤러가 전달한 ModelAndView 값을 이용해서 만듬
ㄹ. 뷰 관련 템플릿(jsp etc...) 로 화면을 만든다.


아니면 개발 과정으로 설명하자면

ㄱ. 클라이언트의 요청을 받을 DispaatcherServlet 을 web.xml에 선언한다.
ㄴ. 클라이언트의 요청을 처리할 컨트롤러 클래스를 만든다.
ㄷ. 컨트롤러가 만든 ModelAndView 데이터를 이용해서 View를 처리할 ViewResolver를 설정한다. ( xml)
ㄹ. Velocity 나 JSP로 뷰를 작성한다.



2. DispatcherServlet 설정
web.xml을 설정하는 과정이다.
/WEB-INF/web.xml
 서블릿과 서블릿 맵핑 정보를 추가하면됨

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
// *.do로 들어오는 클라이언트요청을  dispatcher에서 처리함
<url-pattern>*.do</url-pattern>
<url-pattern>/game/*</url-pattern>
</servlet-mapping>
 
DispatcherServlet은 WEB-INF/ 디렉토리에 위치한 [서블릿이름]-servlet.xml 파일을 스프링 설정파일로 사용한다.

위의 경우 dispatcher 이므로 dispatcher-servlet.xml 파일을 설정파일로 사용한다.
해당 설정파일에는 Controller,ViewResolver,View 등의 빈을 설정한다.


3. Controller 구현
컨트롤러를 구현하려면 @Controller 어노테이션 을 해당 클래스에 적용한다.
@RequestMapping 어노테이션을 이용하면, 클라이언틔 요청을 처리할 메소드를 지정할 수 있다.

@Controller
public class HelloController {

@RequestMapping("/hello.do")
public ModelAndView hello() {
              ModelAndView mav = new ModelAndView();
mav.setViewName("hello");    // 뷰 이름이 hello (.jsp)
mav.addObject("greeting", getGreeting());
return mav;
        }
        ....
}



스프링 MVC는 ModelAndView 말고도 String,Map 등과 같은 타입을 이용해서 뷰이름과,정보를 보낼 수 있다.

당연히 해당 컨트롤러를 DispatcherServlet에서 찾을 수 있도록 스프링 컨테이너의 빈 으로 등록해주어야한다. 

스프링 2.5에서는 컨트롤러 어노테이션에 대해서 추가 작업이 필요하나 3.0에서는 변경되었다.

위의 맵핑에서 정의한 컨트롤러의 메소드에서 ModelAndView 로 결과를 리턴하는데 이 결과와 매칭되는 뷰 구현체를 찾기위해
ViewResolver를 사용한다.  스프링은 여러 벨로시티등의 여러가지 뷰 구현체를 지원하는데 jsp 를 사용할경우 
org.springframework.web.servlet.view.InternalResourceViewResolver 구현체를 빈으로 등록해주면된다.

in [서블릿이름]-servlet.xml 파일안에 
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
// ViewResolver 가 /WEB-INF/view/뷰이름.jsp 를 뷰 JSP로 사용.  위의 컨트롤러에서 view 이름을 hello로 잡았으므로 실제 리턴하는 파일은 
// /WEB-INF/view/hello.jsp 파일이다.  즉 [prefix]뷰이름[suffix] 가 된다.
</bean> 
  

이제 호출하면된다. 
http://localhost:8080/hello.html



자.. 그럼 다시 살펴보면 우선 web.xml에 DispatcherServlet 과 Mapping 설정을 해두었다.
사용자가 특정 url 요청을 하게 되면 Mapping 해두었던 설정에 따라 어떤 dispatcherServlet을 쓸지 확인하고 해당 dispatcherSerlvet 의 설정파일 [dispatcherServlet]-servlet.xml 파일을 읽어서 요청에 맞는 url 패턴을 가진 컨트롤러를 등록된 빈 에서 찾는다.

찾았으면 해당 컨트롤러에 가서 정의된 @RequestMapping 어노테이션중 맞는것을 찾아서 ModelAndView 를 만들고, 리턴한다.

그러면 이를 처리할 ViewResolver 를 찾아야 하는데 그건 [dispatcherServlet이름]-serlvet.xml 파일에 정의된 viewResolver 를 사용해서 

prefix/suffix를 이용한 url을 만든다. 사용자의 눈에는 그 url 이 보이진 않는다. viewResolver가 view를 찾아서 그걸 보여주기만 할뿐 주소의 변경은 없다.

해서 요청 url 패턴이 html 이었다면 .html로 요청한 주소는 그대로이고, viewResolver 에서 만든 주소(by prefix,suffix) 의 대상이 실제 보이게 된다.


'IT > 스프링' 카테고리의 다른 글

filter....  (0) 2012.01.10
DispatcherServlet... more  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09
weaving??  (0) 2012.01.09
Pointcut 표현식... execution , within  (0) 2012.01.06
최범균님의 스프링과 인터넷검색을 기반으로 제가 볼 용도의 글을 쓰는것입니다.

흐음.. 기본적으로 스프링AOP는 스프링의 빈 객체에 대해서만 적용된다.
즉 스프링을 이용하지 않는 객체에 AOP를 적용하고 싶다면...?

스프링의 xml 설정을 바꾸어서 AspectJ를 적용할 수 있다.

AspectJ 를 이용해서 그냥 new 등을 통해 생성된 객체에도 AOP 기능을 쓸 수 있다는 의미이다!!

예제 결과를 보기 전 까지는 이게 뭐지였음; 근데 실행문을 보고 나서야 의미를 알았음;
아마 AspectJ를 몰라서 그런거였겠지;?


객체와 Advice 를 weaving 할 설정은
<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE aspectj PUBLIC 
"-//AspectJ//DTD//EN"
"http://www.eclipse.org/aspectj/dtd/aspectj.dtd">

<aspectj>
// Aspect 의 설정 및 적용할 범위를 정의함 
<weaver>
<include within="madvirus.spring.chap05.board.service.*" />
<include within="madvirus.spring.chap05.board.Article" />
</weaver>
// 어떤 Aspect를 적용할지 정의함
<aspects>
<aspect name="madvirus.spring.chap05.aop.annot.ProfilingAspect"/>
</aspects>
</aspectj>

이렇게 어떤 패키지에 어떤 Aspect를 적용할지 설정 한다.  

 그 다음 스프링 설정 xml 에 <context:load-time-weaver /> 를 추가함

==============================================

AspectJ를 이용한 객체의 DI 처리..
 
스프링 컨테이너를 통해서 생성되는 빈객체는 의존관계처리가 가능하고, 결과 의존성도 줄이고 결합도도 낮출 수 있다.
허나 역시,  스프링 컨테이너를 통하지 않은 생성에서는 제어할 수 없다.

 이를 스프링의 AspectJ 지원기능을 이용하면 스프링 컨테이너밖에서 생성되는 객체에 대해서도 DI를 적용할 수 있게 된다.

해당 클래스에 
 @Configurable 어노테이션을 적용한다.
역시 설정에 weaving을 해야하고,  


'IT > 스프링' 카테고리의 다른 글

DispatcherServlet... more  (0) 2012.01.10
Spring 3.0 MVC 정리  (0) 2012.01.10
weaving??  (0) 2012.01.09
Pointcut 표현식... execution , within  (0) 2012.01.06
JointPoint ..?  (0) 2012.01.06

http://dev.anyframejava.org/anyframe/doc/core/3.2.0/corefw/guide/aop-components.html



Weaving 또는 CrossCutting

AOP가 Core Concerns 모듈의 코드를 직접 건드리지 않고 필요한 기능이 작동하도록 하는 데는 Weaving 또는 CrossCutting이라고 불리는 특수한 작업이 필요하다. Core Concerns 모듈이 자신이 필요한 Crosscutting Concerns 모듈을 찾아 사용하는 대신에 AOP에서는 Weaving 작업을 통해 Core Concerns 모듈의 사이 사이에 필요한 Crosscutting Concerns 코드가 동작하도록 엮어지게 만든다. 이를 통해 AOP는 기존의 OOP로 작성된 코드들을 수정하지 않고도 필요한 Crosscutting Concerns 기능을 효과적으로 적용해 낼 수 있다.

Weaving은 기존의 자바 언어와 컴파일러에서는 쉽게 구현할 수 있는 방법이 아니었으며 본격적인 AOP 기술이 등장한 것은 1990년대 후반 제록스 PARC 연구소에서 그레거 킥제일(Gregor Kiczales)에 의해 AspectJ가 개발되면서라고 볼 수 있다. 
Weaving을 처리하는 방법은 다음과 같이 3가지가 존재한다.
Weaving 방식
설명
Compiletime Weaving별도 컴파일러를 통해 Core Concerns 모듈의 사이 사이에 Aspect 형태로 만들어진 Crosscutting Concerns 코드들이 삽입되어 Aspect가 적용된 최종 바이너리가 만들어지는 방식이다. (ex. AspectJ, ...)
Loadingtime Weaving별도의 Agent를 이용하여 JVM이 클래스를 로딩할 때 해당 클래스의 바이너리 정보를 변경한다. 즉, Agent가 Crosscutting Concerns 코드가 삽입된 바이너리 코드를 제공함으로써 AOP를 지원하게 된다. (ex. AspectWerkz, ...)
Runtime Weaving소스 코드나 바이너리 파일의 변경없이 Proxy를 이용하여 AOP를 지원하는 방식이다. Proxy를 통해 Core Concerns를 구현한 객체에 접근하게 되는데, Proxy는 Core Concerns 실행 전후에 Cross Concerns를 실행한다. 따라서 Proxy 기반의 Runtime Weaving의 경우 메소드 호출시에만 AOP를 적용할 수 있다는 제한점이 있다. (ex. Spring AOP, ...)


'IT > 스프링' 카테고리의 다른 글

Spring 3.0 MVC 정리  (0) 2012.01.10
AspectJ in Spring?  (0) 2012.01.09
Pointcut 표현식... execution , within  (0) 2012.01.06
JointPoint ..?  (0) 2012.01.06
Advice..?  (0) 2012.01.06

+ Recent posts