2017-07-22 6 views
0

私はSpring Socialで小さなGroovyアプリケーションを使用して、Twitterからストリームを消費しています。私は今、いくつかの詳細を含め、私が受け取るすべてのツイートを記録したい。Groovyで所有していないクラスのtoStringをオーバーライドします

Tweetクラスは自分自身のコードの中だろう場合は、私は簡単に素敵なログ出力を取得するには、この操作を行うことができます。

import groovy.transform.ToString 

@ToString 
class Tweet { 
    // fields... 
} 

しかし、私がログインするクラスは、春社会の内部にあることから、私ができる

」それをしないでください。 toStringメソッドをオーバーライドする "Groovy"の方法はありますか?

toStringを追加すると、すべてのログ出力で明示的にtoStringを呼び出すことは望ましくないため、metaClassにクロージャを適用しても実際には役に立ちません。

org.springframework.social.twitter.api.Tweet.metaClass.toString = { 
    "${delegate.field1}, ${delegate.field2}" 
} 

// still prints "received tweet [[email protected]]" 
log.info("received tweet [{}]", tweet) 

// prints "received tweet [field1 field]" 
log.info("received tweet [{}]", tweet.toString()) 
+2

を 'Tweet.metaClass.toString = { "$ delegate.field1 $ delegate.field2"}'? –

+0

一般的に私はこれをやってはいけませんが、見つけるのは難しく、適切な場所に移動するのが難しく、コードがJavaから呼び出された場合は動作しません。 1つ以上の 'Tweet'インスタンスを含むものが必要ですか?なぜtoStringメソッドをそこに置かないのですか? –

+0

@tim_yatesそれは本当です、私はデコレータのために行くだろう選択肢があれば、それは間違いなくクリーナーソリューションです。 –

答えて

1

はい、できます。 Groovyには、metaClass機能を使用して既存のクラスに新しいメソッドを注入する機能があります。クラスのメソッドを呼び出すと、いわゆるメタクラスレジストリが検査され、そのクラスインスタンスにmetaClass拡張メソッドが存在するかどうかが確認されます。

単に定義:

Tweet.metaClass.toString = {"${delegate.field}, ${delegate.anotherField}"}

+0

これはログ出力では機能しません。私は質問を更新しました – Patrick

+0

TweetがJavaでないGroovyクラスであれば、これはあなたが行ける限りです。 groovyのドキュメントまたはこのトピックを見てください:https://stackoverflow.com/questions/1927796/using-groovy-metaclass-to-overwrite-methods#2404388 –

+2

厳密には当てはまりません。 Groovyから呼び出された場合は動作しますが、Javaから呼び出された場合は動作しません。 Groovyクラスにログインしている限り、問題ありません。 Javaクラスがログに記録されている場合、それは動作しません –

関連する問題