JavaRush /Java Blog /Random-JA /春は怠け者のためのものです。基礎、基本概念、コード付きの例。パート2
Стас Пасинков
レベル 26
Киев

春は怠け者のためのものです。基礎、基本概念、コード付きの例。パート2

Random-JA グループに公開済み
前回の記事 では、Spring とは何か、bin とは何か、そしてコンテキストについて簡単に説明しました。今度は、すべてがどのように機能するかを試してみましょう。 春は怠け者のためのものです。 基礎、基本概念、コード付きの例。 パート 2 - 1Intellij Idea Enterprise Edition を使用して自分で実行します。ただし、私の例はすべて、無料の Intellij Idea Community Edition でも動作するはずです。スクリーンショットに、あなたが持っていない何らかのウィンドウがあるのが見えても、心配しないでください。それはこのプロジェクトにとって重要ではありません :) まず、空の Maven プロジェクトを作成しましょう。これを行う方法を記事で示しました(「 Maven プロジェクトを Web プロジェクトに変える時間です。 」という言葉まで読んでください。その後は、Web プロジェクトの作成方法がすでに示されているため、今は必要ありません)。これを src/main フォルダーに作成しましょう/java は何らかのパッケージです (私の場合は「ru.javarush.info.fatfaggy.animals」と名付けました。好きな名前を付けることができますが、適切な場所で自分の名前に置き換えることを忘れないでください)。Mainそして、メソッドを作成する クラスを作成しましょう
public static void main(String[] args) {
    ...
}
次に、pom.xml ファイルを開き、そこにセクションを追加しますdependencies次に、 Maven リポジトリに移動し、そこで最新の安定バージョンのSpring コンテキストを探し、取得したものをセクション内に貼り付けますdependenciesこのプロセスについては、この記事でもう少し詳しく説明しました(「 Maven での依存関係の接続」セクションを参照)。その後、Maven 自体が必要な依存関係を見つけてダウンロードし、最終的には次のようなものを取得するはずです。
春は怠け者のためのものです。 基礎、基本概念、コード付きの例。 パート 2 - 2
左側のウィンドウには、パッケージとクラスを含むプロジェクトの構造が表示されますMain。中央のウィンドウには、pom.xml がどのように表示されるかが表示されます。また、そこにプロパティセクションを追加し、ソース コードで使用している Java のバージョンとコンパイル先のバージョンを Maven に指示しました。これは、起動時に古いバージョンの Java が使用されているという警告が表示されないようにするためです。実行できますが、実行できません) 右側のウィンドウでは、Spring コンテキストのみを接続したにもかかわらず、コア、Bean、AOP、および式が自動的に追加されたことがわかります。各モジュールを個別に接続し、バージョンを明示的に示してそれぞれの依存関係をメモリに登録することも可能でしたが、今のところは現在のオプションに満足しています。次に、パッケージentities(エンティティ) を作成し、その中に 3 つのクラスCat、 、Dog、を作成しましょうParrot。各動物に名前を付けます (private String nameそこにいくつかの値をハードコードできます)。ゲッター/セッターはパブリックです。次に、クラスに移動しMainmain()メソッドに次のような内容を記述します。
public static void main(String[] args) {
	// create an empty spring context that will search for its beans by annotations in the specified package
	ApplicationContext context =
		new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.entities");

	Cat cat = context.getBean(Cat.class);
	Dog dog = (Dog) context.getBean("dog");
	Parrot parrot = context.getBean("parrot-kesha", Parrot.class);

	System.out.println(cat.getName());
	System.out.println(dog.getName());
	System.out.println(parrot.getName());
}
まず、コンテキスト オブジェクトを作成し、コンストラクターで、Bean の存在をスキャンする必要があるパッケージの名前をそれに指定します。つまり、Spring はこのパッケージを調べて、これが Bean であることを Spring に知らせる特別なアノテーションが付けられたクラスを見つけようとします。その後、これらのクラスのオブジェクトを作成し、そのコンテキストに配置します。その後、このコンテキストから猫を取得します。コンテキスト オブジェクトをアドレス指定するときは、Bean (オブジェクト) を指定するように要求し、必要なオブジェクトのクラスを指定します (ちなみに、ここではクラスだけでなくインターフェイスも指定できます)。その後、Spring はこのクラスのオブジェクトを返し、それを変数に保存します。次に、Spring に「dog」という Bean を取得してもらいます。Spring がクラス オブジェクトを作成するとき、Dog(作成される Bean の名前が明示的に指定されていない場合)、オブジェクトのクラスの名前を小文字のみで表す標準名が付けられます。したがって、私たちのクラスは という名前なのでDog、そのような Bean の名前は「dog」になります。そこにオブジェクトがある場合BufferedReader、Spring はそれにデフォルト名「bufferedReader」を付けます。この場合 (Java の場合)、そのようなオブジェクトがどのクラスになるか正確な確信はないため、単純に特定のクラスを返しObject、それを手動で必要な型にキャストしますDog。クラスを明示的に示すオプションの方が便利です。3 番目のケースでは、クラスと名前によって Bean を取得します。単純に、コンテキスト内に 1 つのクラスの複数の Bean が存在する状況があり、どの特定の Bean が必要かを示すために、その名前を示します。ここでもクラスを明確に示したので、キャストする必要がなくなりました。 重要!Spring が指定した要件に従って複数の Bean を見つけたことが判明した場合、どの Bean を提供するかを決定できず、例外がスローされます。したがって、そのような状況が起こらないように、どの箱が必要であるかをできるだけ正確に彼に示すようにしてください。Spring が条件に従ってコンテキスト内で 1 つの Bean を見つけられなかった場合も、例外がスローされます。それでは、動物の名前を画面に表示して、それらが実際に必要なオブジェクトであることを確認するだけです。しかし、ここでプログラムを実行すると、Spring がそのコンテキスト内で必要な動物を見つけることができないと宣言していることがわかります。これは、彼がこれらの豆を作成しなかったため起こりました。すでに述べたように、Spring はクラスをスキャンするときに、そこで「その」Spring アノテーションを探します。そして、それが見つからない場合は、そのようなクラスを Bean を作成する必要があるクラスとして認識しません。@Componentこれを修正するには、動物クラスのクラスの前に 注釈を追加するだけです。
@Component
public class Cat {
	private String name = "Barsik";
	...
}
しかし、それだけではありません。このクラスの Bean に特定の名前を付ける必要があることを Spring に明示的に示す必要がある場合は、この名前をアノテーションの後の括弧内に指定できます。たとえば、後でこのオウムを受け取るparrot-keshaことになるオウムの箱にSpring が必要な名前を付けるにはmain、次のようなことを行う必要があります。
@Component("parrot-kesha")
public class Parrot {
	private String name = "Kesha";
	...
}
これが自動構成の 要点です。クラスを作成し、必要なアノテーションを付けて、クラスを含むパッケージを Spring に指示します。パッケージを通じて、アノテーションが検索され、そのクラスのオブジェクトが作成されます。ちなみに、Spring は 注釈 だけでなく@Component、この注釈から継承される他のすべての注釈も検索します。たとえば@Controller、、、、など@RestControllerです。これらについては、今後の記事で説明します。次に、 Java 構成を使用して同じことを試してみましょう。まず、クラスからアノテーションを削除しましょう。タスクを複雑にするために、これらが自分で作成したクラスではなく、簡単に変更したり、アノテーションを含めて何かを追加したりできると想像してみましょう。まるでこれらのクラスがどこかの図書館に詰め込まれているかのようです。この場合、春までに受け入れられるようにこれらのクラスを編集することはできません。しかし、これらのクラスのオブジェクトが必要です。ここでは、そのようなオブジェクトを作成するための Java 構成が必要になります。まず、パッケージ (たとえば ) を作成し、その中に通常の Java クラス (たとえば) を作成し、それにアノテーションを付けます。@Service@Repository@ComponentconfigsMyConfig@Configuration
@Configuration
public class MyConfig {
}
main()ここで、メソッド内でコンテキストを作成する方法を 少し調整する必要があります。そこで設定を使用してクラスを直接指定することもできます。
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class);
Bean を作成する複数の異なるクラスがあり、それらのいくつかを一度に接続したい場合は、単純にそれらをカンマで区切って指定します。
ApplicationContext context =
	new AnnotationConfigApplicationContext(MyConfig.class, MyAnotherConfig.class);
それらの数が多すぎて、それらをすべて一度に接続したい場合は、単にそれらが含まれているパッケージの名前をここに指定します。
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.configs");
この場合、Spring はこのパッケージを調べて、 注釈 が付いているすべてのクラスを検索します@Configuration。構成がさまざまなパッケージに分割されている非常に大きなプログラムがある場合は、構成をカンマで区切ってパッケージの名前を指定するだけです。
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals.database.configs",
		"ru.javarush.info.fatfaggy.animals.root.configs",
		"ru.javarush.info.fatfaggy.animals.web.configs");
または、それらすべてに共通するパッケージの名前:
ApplicationContext context =
	new AnnotationConfigApplicationContext("ru.javarush.info.fatfaggy.animals");
好みに応じて実行できますが、構成でクラスを指定するだけの最初のオプションがこのプログラムに最も適しているように思えます。コンテキストを作成するとき、Spring はアノテーションが付けられたクラスを検索し@Configuration、それらのクラスのオブジェクトをそれ自体で作成します。その後、アノテーション が付けられたこれらのクラスのメソッドの呼び出しを試みます@Bean。これは、そのようなメソッドがコンテキスト内に既に配置されている Bean (オブジェクト) を返すことを意味します。さて、Java 構成を使用してクラスに猫、犬、オウムの Bean を作成しましょう。これは非常に簡単に行われます。
@Bean
public Cat getCat() {
	return new Cat();
}
私たちが猫を自分たちで手動で作成して Spring に与えたことが判明し、Spring はすでに私たちのこのオブジェクトを彼のコンテキストに配置していました。Bean の名前を明示的に指定しなかったため、Spring は Bean にメソッド名と同じ名前を付けます。この例では、Cat's Bean の名前は「getCat」になります。しかし、main-e では依然として名前ではなくクラスで猫を取得しているため、この場合、このビンの名前は重要ではありません。同じ方法で犬を使った Bean を作成しますが、Spring はそのような Bean にメソッド名を付けることに注意してください。オウムを使用して Bean に明示的に名前を付けるには、アノテーションの後の括弧内にその名前を指定するだけです@Bean
@Bean("parrot-kesha")
public Object weNeedMoreParrots() {
	return new Parrot();
}
ご覧のとおり、ここでは戻り値の型を指定しObject、メソッドを何でも呼び出しています。ここで明示的に設定するため、これは Bean の名前にはまったく影響しません。ただし、戻り値の型とメソッド名は、いきなりではなく、ある程度明確に示す方がよいでしょう。1年後にこのプロジェクトをオープンするとき、自分自身のためにも。:) 次に、ある Bean を作成するために別の Bean を使用する必要がある状況を考えてみましょう。たとえば、Cat Bean 内の猫の名前をオウムの名前と文字列「-killer」で構成したいとします。問題ない!
@Bean
public Cat getCat(Parrot parrot) {
	Cat cat = new Cat();
	cat.setName(parrot.getName() + "-killer");
	return cat;
}
ここで Spring は、この Bean を作成する前に、すでに作成されている Parrot Bean をここに転送する必要があることを認識します。したがって、オウムを作成するメソッドが最初に呼び出され、次にこのオウムを猫を作成するメソッドに渡すように、メソッドへの呼び出しのチェーンを構築します。ここで依存性注入と呼ばれるものが機能します。Spring 自体が必要な Parrot Bean をメソッドに渡します。アイデアに変数に関する問題がある場合は、オウムを作成するメソッドの戻り値の型をからparrotに変更することを忘れないでください。さらに、Java 構成を使用すると、Bean を作成するメソッド内であらゆる Java コードを実行できます。他の補助オブジェクトを作成したり、Spring アノテーションでマークされていないメソッドも含めて他のメソッドを呼び出したり、ループや条件を作成したり、思いついたことなら何でもできます。これらすべては、自動構成を使用しても実現できず、ましてや XML 構成を使用しても実現できません。 ObjectParrot では、もっと楽しい問題を見てみましょう。ポリモーフィズムとインターフェイスを使用して:) インターフェイスを作成しWeekDay、このインターフェイスを実装する 7 つのクラス、 、Monday、、、、を作成しましょう。インターフェイス内に、対応するクラスの曜日の名前を返すメソッドを作成しましょう。つまり、クラスは" " などを返します。アプリケーションを起動するときのタスクは、現在の曜日に対応するコンテキストに Bean を配置することだとします。インターフェースを実装するすべてのクラスのすべての Bean ではなく、必要な 1 つの Bean のみです。次のようなことができます: TuesdayWednesdayThursdayFridaySaturdaySundayString getWeekDayName()MondaymondayWeekDay
@Bean
public WeekDay getDay() {
	DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
	switch (dayOfWeek) {
		case MONDAY: return new Monday();
		case TUESDAY: return new Tuesday();
		case WEDNESDAY: return new Wednesday();
		case THURSDAY: return new Thursday();
		case FRIDAY: return new Friday();
		case SATURDAY: return new Saturday();
		default: return new Sunday();
	}
}
ここで、戻り値の型はインターフェイスであり、メソッドは現在の曜日に応じてインターフェイス実装クラスの実際のオブジェクトを返します。メソッド内でmain()これを行うことができます:
WeekDay weekDay = context.getBean(WeekDay.class);
System.out.println("It's " + weekDay.getWeekDayName() + " today!");
今日は日曜日だということが分かりました :) 明日プログラムを実行すると、コンテキスト内にまったく異なるオブジェクトが表示されると確信しています。ここでは単にインターフェースによって Bean を取得していることに注意してくださいcontext.getBean(WeekDay.class)。Spring はコンテキストを調べて、どの Bean がそのようなインターフェースを実装しているかを確認し、それを返します。さて、WeekDaytype の変数に type のオブジェクトが存在することがわかりSunday、この変数を操作するときに、すでによく知られているポリモーフィズムが始まります。:) そして、組み合わせたアプローチについて少し説明します。このアプローチでは、一部の Bean は、アノテーション付きのクラスの存在に対するパッケージのスキャンを使用して Spring 自体によって作成され@Component、他のいくつかの Bean は Java 構成を使用して作成されます。Catこれを行うには、クラスとDogParrot注釈が付けられていた元のバージョンに戻りましょう@Component。春までにパッケージの自動スキャンを使用して動物用の箱を作成したいとしますentitiesが、先ほどと同じように曜日を使用して箱を作成するとします。必要なのは、 -th アノテーションMyConfigでコンテキストを作成するときに指定するクラス レベルで追加し、スキャンする必要があるパッケージと自動的に作成される必要なクラスの Bean を括弧内に示すことだけです。 main@ComponentScan
@Configuration
@ComponentScan("ru.javarush.info.fatfaggy.animals.entities")
public class MyConfig {
	@Bean
	public WeekDay getDay() {
		DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
		switch (dayOfWeek) {
			case MONDAY: return new Monday();
			case TUESDAY: return new Tuesday();
			case WEDNESDAY: return new Wednesday();
			case THURSDAY: return new Thursday();
			case FRIDAY: return new Friday();
			case SATURDAY: return new Saturday();
			default: return new Sunday();
		}
	}
}
コンテキストを作成するときに、Spring はクラスを処理する必要があることを認識していることがわかりますMyConfig。彼はそこに入り、パッケージ " " をスキャンしてそれらのクラスの Bean を作成する必要があることを確認した後、クラスからru.javarush.info.fatfaggy.animals.entitiesメソッドを実行し、タイプ Bean をコンテキストに追加します。このメソッドでは、必要なすべての Bean (動物オブジェクトと曜日を含む Bean の両方) にアクセスできるようになりました。Spring がいくつかの XML 構成も取得することを確認する方法 - 必要に応じてインターネットで自分でググってください :) 要約:getDay()MyConfigWeekDaymain()
  • 自動構成を使用してみてください。
  • 自動構成中に、Bean を作成する必要があるクラスを含むパッケージの名前を指定します。
  • このようなクラスには注釈が付けられています@Component;
  • Spring は、そのようなクラスをすべて調べて、それらのオブジェクトを作成し、コンテキストに配置します。
  • 何らかの理由で自動構成が適さない場合は、Java 構成を使用します。
  • この場合、必要なオブジェクトを返すメソッドを持つ通常の Java クラスを作成し、@Configurationコンテキストの作成時に構成で特定のクラスを指定するのではなく、パッケージ全体をスキャンする場合に備えて、そのようなクラスにアノテーションを付けます。
  • Bean を返すこのクラスのメソッドには、アノテーションが付いています@Bean
  • Java 設定を使用するときに自動スキャンを有効にしたい場合は、アノテーションを使用します @ComponentScan
何も不明な点がある場合は、数日以内にこの記事を読んでみてください。そうですね、または Javarash の初期レベルにある場合は、春を学ぶには少し早いかもしれません。Java でのプログラミングに自信が持てるようになったら、いつでもこの記事に戻っていただけます。すべてが明確な場合は、お気に入りのプロジェクトの一部を Spring に転送してみてください :) 何かが明確だが、何かがそれほどではない場合は、コメントしてください :) どこかに足を踏み入れたり、愚かなことを書いたりした場合は、提案やコメントもあります) 次の記事では、 spring-web-mvcについて詳しく説明し、spring を使用して単純な Web アプリケーションを作成します。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION