これはSpringBootやGroovyの機能に依存する質問ではありませんが、Springに関する質問やXMLベースの設定の違いはどういう意味ですか:application.xml
、対Javaベースのコンフィグレーション、および/または@Component
のような注釈の使用を使用します。
ドキュメントを探しているなら、Javaベースの設定に関するSpringのドキュメントを参考にして、ほとんどの情報を得ることができます。良いスタートは5.12.1 Basic concepts: @Bean and @Configurationです。
あなたの質問へのコメントで述べたように、私は@Canonical
注釈がこれに全く影響しないと思います。 @Canonical
は、単純に複合アノテーションであり、一般的に使用されるメソッドをGroovyクラスに自動的に生成するために使用されます。具体的には、@Canonical
GroovyDocに直接述べたように:
@Canonicalメタアノテーションは@EqualsAndHashCode、@ToStringと@TupleConstructor注釈を組み合わせます。これは、可変クラスの作成を支援するために使用されます。これは、位置コンストラクター、equals、hashCode、およびかなりのtoStringをあなたのクラスに追加するAST変換を実行するようにコンパイラーに指示します。
Java、Spring、Groovy、またはSpring Bootのいずれを使用しているかにかかわらず、Beanのアプリケーションへの接続方法には影響しません。
これらのことはすべて、Spring BootとGroovyを使用してどのように要件を達成すると思いますか?
具体的な例を挙げて説明するとよいでしょう。 良い例を提供するために、ビルドツールとしてGradleを使用し、選択言語としてGroovyを使用して、Test SpringBootプロジェクトを作成しました。この例では、Groovyクラスをcom.app.bootinjection
パッケージに配置しています。ここでは、フォルダやパッケージ構造を示すスクリーンショットである:
buildscript {
ext {
springBootVersion = '1.3.1.RELEASE'
}
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'spring-boot'
repositories {
jcenter()
mavenCentral()
}
dependencies {
compile('org.codehaus.groovy:groovy-all:2.4.5')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.apache.tomcat.embed:tomcat-embed-jasper:8.0.30')
compile('com.fasterxml.jackson.core:jackson-core:2.7.1')
compile('com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.7.1')
}
springBoot{
mainClass = 'com.app.Application'
}
task wrapper(type: Wrapper) {
gradleVersion = '2.9'
}
注:私は、次の内容を画像で見られるbuild.gradle
ファイルを、
アプリケーションを構築するために作成しましたbuild.gradle
ファイルで、私は2つのコンパイル時の依存関係をJacksonライブラリに追加しました。 JSON出力をサポートする 'core'ライブラリ、ブラウザのようなクライアントでJSON出力をうまくフォーマットする 'dataformat'ライブラリ。
Application.groovy:
これはSpringBootアプリケーションをすることですので
、私はmainメソッドが含まれており、我々のアプリケーションを起動する@SpringBootApplication
アノテーションを付け、簡単なApplication
クラスを作成しましたFizz
、Buzz
、Widget
とHerpDerp
:
package com.app
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.context.ApplicationContext
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args)
}
}
は、私はまた、あなたの質問に記載された各クラスのGroovyのクラス代表を作成しました。それぞれには、
@Canonical
注釈と
@Component
注釈の両方で注釈が付けられます。コンポーネントのスキャンが完了すると、Springは
@Component
アノテーションを参照し、デフォルトではそのクラスの単一の(シングルトンのような)インスタンスを構築し、Beanとして登録します。デフォルトでは、Beanの名前はクラスの名前と同じになり、クラス名の最初の文字はケース下部になります。したがって、
Fizz
クラスはBeanとしてインスタンス化され、Bean名 'fizz'の下に登録されます。詳細については、
Section 5.10.1 @ComponentのSpringドキュメントを参照してください。ちなみに、
@Scope(value = "prototype")
を使用して、注入するたびに作成された新しいものを持つようにBeanの 'スコープ'を変更することができます。しかし、絶対に必要な場合にのみそれを行うことをお勧めします。
Fizz.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
@Canonical
@Component
class Fizz {
boolean checked
String umberGUID = 0
}
注:私はデモ/出力のために0の値にumberGUID
をデフォルトとしています。
Buzz.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
import javax.annotation.Resource
@Canonical
@Component
class Buzz {
@Resource
Fizz fizz1
int value
}
Widget.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
import javax.annotation.Resource
@Component
@Canonical
class Widget {
@Resource
Fizz fizz2
@Resource
Buzz buzz
@Resource
String magicalNumber
}
HerpDerp.groovy:
package com.app.bootinjection
import groovy.transform.Canonical
import org.springframework.stereotype.Component
import javax.annotation.Resource
@Component
@Canonical
class HerpDerp {
@Resource
Widget widget
@Resource
Fizz fizz
}
注豆を私たちのオブジェクトに注入するための@Resource
の使用。私たちのプロジェクトでは、最初に@Autowired
から@Inject
に、そして@Resource
というアノテーションに切り替えました。ほとんどの場合、私たちは@Resource
がより適切であり、私たちのプロジェクトでより頻繁に働くことを発見しました。たとえば、クラスBuzz
のFizz fizz1
の宣言に注意してください。 @Resource
を使用して、適切なインスタンスFizz
を挿入します。ここでは、Bean名はfizz1
と一致します。なぜどちらかを使用する際に/上より明確にするため、州春のドキュメントのセクション5.9.3を参照してください:
あなたが名前で、アノテーション駆動型の注入を表現する場合
ヒント
、しないでください技術的に@Qualifier値によってBean名を参照できる場合でも、主に@Autowiredを使用します。代わりに、JSR-250 @Resource注釈を使用します。これは、特定のターゲットコンポーネントを固有の名前で識別するために意味的に定義されています。宣言されたタイプは、マッチングプロセスとは関係ありません。
この意味の違いの特定の結果として、コレクションまたはマップタイプとして定義されたBeanは、@Autowiredを通じて注入できません。タイプマッチングが適切に適用されないためです。このようなBeanには@Resourceを使用し、特定のコレクションまたはマップBeanを一意の名前で参照します。
@Autowiredは、フィールド、コンストラクタ、および複数引数のメソッドに適用され、パラメータレベルで修飾子注釈を絞り込むことができます。対照的に、@Resourceは単一の引数を持つフィールドとBeanのプロパティ設定メソッドに対してのみサポートされています。したがって、注入ターゲットがコンストラクタまたは複数引数のメソッドの場合は、修飾子を使用してください。
私はどのようにして同じインスタンスの複数の豆を異なる名前で宣言しますか?@Component
注釈だけを使用して、クラスのインスタンスを1つ作成して、クラス名(最初の文字は小文字)にデフォルト設定することができます。 @Component
を使用するときに、デフォルトを上書きする名前を指定することもできます。例:@Component("myBean")
。それでも、1つのインスタンスが作成されます。前述のように、@Scope("prototype")
アノテーションを使用して 'スコープ'を指定することもできます。さて、Beanが注入されるたびに、新しいインスタンスが作成され注入されます。
作成するBeanの数を制御し、固有の名前を指定し、固有の名前を挿入する場合は、より構成可能な解決策が必要です。 XML構成と比較した場合の好ましい解決策は、Javaベースのソリューションです。任意のクラスを作成し、@Configuration
注釈を使用して設定して、Springにこのクラスが設定情報を提供することを示すことができます。この例では、私はApplicationConfiguration
クラスを作成しました:
ApplicationConfiguration.groovy:FIZZ1とfizz2:
package com.app
import com.app.bootinjection.Fizz
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class ApplicationConfiguration {
@Bean
Fizz fizz1(){
new Fizz(checked: true, umberGUID: 1)
}
@Bean
Fizz fizz2(){
new Fizz(checked: false, umberGUID: 2)
}
@Bean
@Scope("prototype")
String magicNumber(){
System.currentTimeMillis()
}
}
を構成では、我々は2つのユニークフィズインスタンスを作成するためのFizz
クラスの2つの方法を作成します。メソッドの名前はBeanの名前になりますので、メソッドfizz1()
とfizz2)
です。また、それぞれのインスタンスが1つだけ作成されることにも注意してください。 SpringはBeanをインスタンス化し、それぞれのインスタンスを1つだけ作成します。あなたはBuzz
クラスに戻って見れば
は今、あなたは私たちが、構成クラスで宣言されたBean名と一致するBean名fizz1
を、一致するFizz
クラスのインスタンスを注入する@Resource
アノテーションを使用していることがわかります。同じことがについてはWidget
に該当します。また、デモンストレーションの目的で、fizz
と呼ばれるHerpDerp
クラスにFizz
インスタンスも挿入することに注意してください。クラスに@Component
と注釈を付けたので、Springがコンポーネントスキャンを実行すると、注釈付きクラスが表示され、デフォルトでfizz
の別のインスタンスが作成されます。
コンフィグレーションクラスでは、magicNumber()
という@Bean
というアノテーションが付いた別のBeanメソッドがあります。私たちは毎回ユニークな魔法の数字を注入したいので、その豆にプロトタイプ:Scope("prototype")
のスコープを付けて注釈を付けました。次いで、タイプString
の豆を、必要に応じてWidget
クラスに注入する。
最後に、すべてをまとめて、私は単純にHerpDerp
のBeanインスタンスを挿入して返すREST Webサービスコントローラを作成しました。そしてそれをJSONにシリアル化して、期待される出力を示します。結果はhttp://localhost:8080にアクセスして見られる:
TestController.groovy:私はこれをカバーし、包括的なデモであることが証明さを願ってい
<HerpDerp xmlns="">
<widget>
<fizz2>
<checked>false</checked>
<umberGUID>2</umberGUID>
</fizz2>
<buzz>
<fizz1>
<checked>true</checked>
<umberGUID>1</umberGUID>
</fizz1>
<value>0</value>
</buzz>
<magicalNumber>1464240486303</magicalNumber>
</widget>
<fizz>
<checked>false</checked>
<umberGUID>0</umberGUID>
</fizz>
</HerpDerp>
:
package com.app.bootinjection
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import javax.annotation.Resource
@RestController
class TestController {
@Resource
HerpDerp herpDerp
@RequestMapping("/")
def index(){
[herpDerp]
}
}
の結果として出力してあなたが達成しようとしているトピック。 Spring/SpringBootは、探している結果を簡単に生成することができます。がんばろう!
春と春のブートプロジェクトには、いくつかの最高のドキュメントがあります。 DIセクションを読むことから始めることをお勧めします。また、GitHubリポジトリに含まれている多数のサンプルプロジェクトを指摘しています。 – cjstehno
closevote @cjstehno(+1)に感謝しますが、この質問はSpring DI ** + Groovy **、特に '@ Canonical'の使用に関するものです。私はすでに読んだことをもとにして、ドキュメントから抽出したものを説明して研究を示しました。この質問は**詐欺ではなく、[SSCCE](http://sscce.org)ですので、クローズ投票をお控えください!ドキュメントには、私の特定の問題をどのように解決するかについてのヒント*が含まれていますが、具体的なものはありません。 – smeeb
@smeebので、あなたの質問にいくつかの点が不明です。 1)あなたの質問で '@ Canonical'の妥当性は何ですか? '@ Canonical'は、いくつかの他のGroovyアノテーション、@EqualsAndHashCode、@ToStringおよび@TupleConstructorアノテーションを組み合わせた複合アノテーションです。これらのすべては、equalsおよびhashCode、toStringメソッド、およびデフォルトコンストラクタのデフォルト実装を作成するだけです。その影響はなく、Spring/Spring Bootに関連しています。 – pczeus