사용자 도구

사이트 도구


groovy:meta_programming

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
groovy:meta_programming [2016/08/28 13:28]
kwon37xi
groovy:meta_programming [2016/08/30 08:37] (현재)
kwon37xi [대량의 메소드 추가 기법]
줄 3: 줄 3:
  
 ===== GroovyInterceptable ===== ===== GroovyInterceptable =====
-  * Groovy 객체가 [[http://docs.groovy-lang.org/latest/html/api/groovy/lang/GroovyInterceptable.html|GroovyInterceptable]]을 구현하고 있다면 모든 메소드 호출시 메소드의 존재 여부와 상관없이 항상 ''invokeMethod''가 호출된다.+  * Groovy 객체가 [[http://docs.groovy-lang.org/latest/html/api/groovy/lang/GroovyInterceptable.html|GroovyInterceptable]]을 구현하고 있다면 모든 메소드 호출시 메소드의 존재 여부와 상관없이 항상 ''invokeMethod''가 호출된다. Groovy 코드를 직접 작성할 때 사용가능. 
 +  * ''GroovyInterceptable''을 구현하지 않고 ''invokeMethod''만 구현했다면,  
 +    * 존재하지 않는 메소드에 대해서만 ''invokeMethod'' 호출 
 +    * 존재하지 않는 메소드 호출시 ''invokeMethod'' 없으면 ''missingMethod'' 호출 
 +  * 객체 ''MetaClass''에 ''invokeMethod'' 구현하면 메소드의 존재 여부와 상관없이 항상 ''invokeMethod'' 호출 
 + 
 +===== MetaClass Interception ===== 
 +  * Java class나 직접 작성하지 않고 의존하는 외부 Groovy class 등에 대한 interception 가능. 
 +  * 메소드 존재 여부와 상관없이 항상 호출됨. 
 +<code groovy> 
 +YourClass.metaClass.invokeMethod = { String methodName, methodArgs -> 
 +  //구현 
 +  // 객체 자신을 가리킬 때는 delegate 를 사용한다. closure 이기 때문. 
 +  // 존재하지 않는 메소드 호출을 metaClass.invokeMissingMethod() 에 위임시킬 수 있다. 
 +  // invokeMissingMethod는 다시 missingMethod()에 위임한다. 
 +
 +</code> 
 + 
 +===== ExpandoMetaClass ===== 
 +  * [[http://docs.groovy-lang.org/latest/html/api/groovy/lang/ExpandoMetaClass.html|ExpandoMetaClass]] : Groovy Meta Programming의 핵심 클래스 
 +<code groovy> 
 +// 아래처럼 metaClass에 메소드를 추가해줘야 metaClass 구현체가 ExpandoMetaClass로 변경됨. 
 +Integer.metaClass.invokeMethod = { String name, args -> /* */ } 
 +println Integer.metaClass.getClass().name // ExpandoMetaClass 
 +</code> 
 + 
 +==== 대량의 메소드 추가 기법 ==== 
 +<code groovy> 
 +Integer.metaClass { 
 +    // 메소드 추가 
 +    daysFromNow = { -> 
 +        Calendar today = Calendar.instance 
 +        today.add(Calendar.DAY_OF_MONTH, delegate) 
 +        today.time 
 +    } 
 + 
 +    // 프라퍼티 추가. 괄호없이 호출가능. 
 +    getDaysFromNow = { -> 
 +        Calendar today = Calendar.instance 
 +        today.add(Calendar.DAY_OF_MONTH, delegate) 
 +        today.time 
 +    } 
 + 
 +    // static method 추가 
 +    'static'
 +        isEven = { val -> val % 2 == 0 } 
 +    } 
 + 
 +    // 생성자 추가 
 +    constructor = { Calendar calendar -> 
 +        new Integer(calendar.get(Calendar.DAY_OF_YEAR)) 
 +    } 
 + 
 +    constructor = { int val -> 
 +        println "Intercepting constructor call" 
 +        constructor = Integer.class.getConstructor(Integer.TYPE) 
 +        constructor.newInstance(val) 
 +    } 
 +
 + 
 +println 5.daysFromNow() 
 +println 5.daysFromNow // without parentheses 
 + 
 +println "Is 2 even? " + Integer.isEven(2) 
 +println "Is 3 even? " + Integer.isEven(3) 
 +println new Integer(4) 
 +println new Integer(Calendar.instance) 
 +</code>
  
groovy/meta_programming.1472360303.txt.gz · 마지막으로 수정됨: 2016/08/28 13:28 저자 kwon37xi