2013-03-19 2 views
4

Grails (적어도 현재 버전 2.2까지)에서 taglib는 클로저이다. 특정 taglib 클로저의 경우, "around"타입 advice를 사용하고 싶습니다/인터셉터에서 클로저를 감싸고 싶습니다. ,클로저를위한 aspect (--like) 함수

class SimpleTagLib { 
    def emoticon = { attrs, body -> 
     out << body() << (attrs.happy == 'true' ? " :-)" : " :-(") 
    } 
} 

태그 라이브러리 코드를 수정하지 않고, 이제 긴 "이모티콘이 '에 걸리는 나는 시간에 싶습니다

는의가 바로 Grails의 문서에서이 태그 라이브러리가 말을하자, 그것을 다른 방법을 넣으려면 실행.

스프링 AOP (그리고 다른 모든 AOP는 찾을 수 있습니다)은 Java 메소드에서만 작동하는 것으로 보이며 taglib는 항상 클로저를 기반으로합니다. "around"pointcut은 이것에 완벽 할 것이다. 그러나 그것을 작동시키는 방법을 이해할 수는 없다. 나는 내가 다음 서비스 믹스 인 범주에 공개 폐쇄로두고 비슷한 작성했습니다

+0

'getProperty' 또는'missingProperty'에서 around pointcut은 어떨까요? Grails가 클로저 프로퍼티를 얻는 방법을 모르겠다. – Will

+0

더 간단한 접근법은 메타 클래스로 클로저의 동작을 변경하는 것이다. –

+0

JIRA 기능 요청을 Grails Jira에 추가하십시오. 이것은 Grails에서 누락 된 기능입니다. 한 가지 더 많은 사용 사례 (taglib 캐싱)에 대해서는 http://jira.grails.org/browse/GRAILS-6680?focusedCommentId=56175&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-56175를 참조하십시오. –

답변

1

: 다른 클래스에서

// TimingCategory.groovy 
/** 
* Provides common AOP timing functionality to Services which mixin this category. 
*/ 
class TimingCategory { 

    static Closure timer = { String label = "The call", Closure closure -> 
     Long start = System.currentTimeMillis() 
     def result = closure.call() 
     Long end = System.currentTimeMillis() 
     Long duration = end - start 
     log.warn "${label} took ${duration} ms" 
     return result 
    } 
} 

, 당신은 방금과 같은 timer 폐쇄를 참조 :

@Mixin(TimingCategory) 
public class WhateverService { 

    public String doSomeWork() { 
     timer "Doing a lot of work", { 
      1000.times { doSomething() } 
      someMethodWithAStringReturnValue() 
     } 
    } 
} 

로그 출력이 입니다. "WARN : 많은 작업을 수행하는 데 nn 밀리 초가 걸렸습니다"doSomeWork 메서드의 반환 값으로 내부 클로저 값을 반환합니다. 당신의 태그 라이브러리의 예를 들어

, 그냥

timer "Writing an emoticon", { 
    // your code 
} 

코드에서 out << ... 포장.

내부 반환 값을 전달할 필요가 없다면 대신 클로저 호출의 결과로 기간을 반환 할 수 있습니다.

업데이트 :

내가 오해했을 수도

- 전혀 태그 라이브러리 코드를 수정하지 않고 태그 라이브러리의 실행을 포장하는 방법을 당신이 요구하는지? 시체를 받아들이고이를 다른 taglib에 전달하여 실행되도록하는 커스텀 태그 라이브러리를 만드는 것은 어떨까요?

나는이 시도했지만 뭔가 같이하지 않은 :

class TimedTagLib { 

    static namespace = "timer" 

    def timedTag = { attrs, body -> 
     timer "Executing the timed tag", { 
      out << body() 
     } 
    } 
} 

그리고

<timer:timedTag><g:emoticon whatever="something">Text</g:emoticon></timer:timedTag> 

업데이트 2처럼 호출 :

좋아, 그래서 그것을 시도했다. 잘 작동합니다.

// TimedTagLib.groovy 
@Mixin(TimingCategory) 
class TimedTagLib { 
    static namespace = "timer" 

    def timedTag = { attrs, body -> 
     def duration = returnTimer "Printing the timed tag", { 
      out << body() 
     } 

     out << "Took ${duration} ms to print" 
    } 
} 

그리고보기 :

// someView.gsp 
<timer:timedTag> 
    <g:formatLocalDate date="${LocalDate.now()}" /> 
</timer:timedTag> 

결과 HTML은 다음과 같습니다 내 최종 코드 (I 번째 타이머 시간을 반환 폐쇄 추가)

03/19/2013 
Took 6 ms to print 

을 그리고 그것은 또한 썼다 로그에.