質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
DI (Dependence Injection)

DI (Dependence Injection)は、「依存性の注入」という概念を指します。オブジェクト間で依存性のあるコードを外部の設定ファイルから注入するソフトウェアパターン設計思想です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

2回答

25573閲覧

コンストラクタに引数が必要なクラスのDIについて

msss

総合スコア33

DI (Dependence Injection)

DI (Dependence Injection)は、「依存性の注入」という概念を指します。オブジェクト間で依存性のあるコードを外部の設定ファイルから注入するソフトウェアパターン設計思想です。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

1グッド

0クリップ

投稿2017/02/17 04:07

編集2017/02/17 08:03

コンストラクタに引数(処理中に値が決定する)が必要なクラスをDIする場合
どのように実装したらよいのでしょうか。

1.基本的にシングルトンなので動的な引数でインスタンス化は出来ないのでしょうか。

2.そのような場合はコンテナ管理させずにnewしてあげるのが一般的なのでしょうか。

java

1@Controller 2public class HogeController { 3 @Autowired 4 private HogeService service; 5 6 void test(){ 7 int i = 1; 8 String s = "test"; 9 10// 本当は以下のようなことがしたいのですが、どのようにすれば良いのでしょうか。 11 HogeService service = new HogeService(i, s); 12 13 service.print(); 14 } 15} 16 17@Service 18public class HogeService { 19 final int a; 20 final String b; 21 22 HogeService (int a, Sting b){ 23 this.a = a; 24 this.b = b; 25 } 26 27 public void print(){ 28 System.out.println(i); 29 System.out.println(s); 30 } 31}

追加(解決策?)

  • new()した方が良いような気もしますがコンテナに登録されたオブジェクトにコンストラクタに引数が渡せました。

java

1@Controller 2public class HogeController { 3 void test(){ 4 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class); 5 TestDI hogeA = (TestDI) context.getBean("getHogeInstance", 1, "@@@"); 6 TestDI hogeB = (TestDI) context.getBean("getHogeInstance", 2, "◆◆"); 7 8 hogeA.print(); 9 hogeB.print(); 10 } 11} 12 13@Service 14public class Test { 15 @Bean 16 @Scope("prototype") 17 HogeService getHogeInstance(int i, String s) { 18 return new HogeService (i, s); 19 } 20} 21 22public class HogeService { 23 final int a; 24 final String b; 25 26 HogeService (int a, Sting b){ 27 this.a = a; 28 this.b = b; 29 } 30 31 public void print(){ 32 System.out.println(i); 33 System.out.println(s); 34 } 35} 36
fa11enprince👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

サンプル

java

1@Configuration 2public class ApplicationConfiguration { 3 4 @Bean 5 @Scope("prototype") //As we want to create several beans with different args, right? 6 String hello(String name) { 7 return "Hello, " + name; 8 } 9} 10 11//and later in your application 12 13AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfiguration.class); 14String helloCat = (String) context.getBean("hello", "Cat"); 15String helloDog = (String) context.getBean("hello", "Dog");

APIリンク

上記をマネすれば、引数が渡せるのでは?

投稿2017/02/17 05:23

liguofeng29

総合スコア801

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msss

2017/02/17 06:12

これは@Autowiredして値を設定するのと何が違うのでしょうか。
msss

2017/02/17 08:05

回答ありがとうございます。 上記の方法を用いてコンテナに登録されたオブジェクトにコンストラクタからnewすることが出来ました。 これが良い方法かどうかはまた別途質問しようと思います。 ありがとうございました。
guest

0

HogeControllerのインスタンスが生成された時点でコンテナから対象のインスタンスが取得されるため、メソッド中で初期値を設定するのは不可能です。

setterなどで設定してあげるか(immutableでやりたいのであればこの方法は使えません。)
コンテナ管理させないか。

ですかね。とりあえずなんでもかんでもコンテナ管理はやめておいたほうがいいです。
コンテナ管理をさせたい理由と実現したいことのイメージがあれば別にアドバイスが出来るかもしれません。

投稿2017/02/17 04:38

7tsuno

総合スコア310

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msss

2017/02/17 04:53

回答ありがとうございます。 ※コードを少し修正しました(コンストラクタ引数をfinalにしました) 特にコンテナ管理させたいわけではないです。 上記の場合はnew()しておくのが一般的という回答でよろしいでしょうか。
7tsuno

2017/02/17 05:01

そうですね。一般的なオブジェクトでコンテナ管理させない場合はコンテナ管理させないほうがいいです。 つまり、new()で取得するのが一般的(一般的かどうかといったら自分はstatic factoryのほうが好きですが)です。 コンテナ管理する対象はロジックだったり、値をリクエスト間で引き継ぎたいオブジェクトだったりです。 ちなみに一般的には@Serviceを付与するのはでサービス層のクラス(ビジネスロジック等)です。
msss

2017/02/17 05:34

◇ロジックの処理も、その業務を行うのに必須の前提条件が必要な場合もあると思います。 そのような場合は全てのメソッドに前提条件の値を渡すことになるのでしょうか。 ◇ちなみに、7tsuno様はコンテナ管理させる場合とさせない場合をどのように切り分けられているのでしょうか。
7tsuno

2017/02/17 08:54

◇ロジックの処理も、その業務を行うのに必須の前提条件が必要な場合もあると思います。 ロジックにフィールドを持たせたいということでしょうか。基本的にはコンテナ管理されたロジックにフィールドを持たせるのは危険です。(スコープにもよりますが他のスレッドやリクエストに値が変更される可能性があるため。) 全てのメソッドに前提条件の値を渡すことになると思います。 ◇コンテナ管理させる場合とさせない場合 設計にもよりますが、Controller, Helper, Service,Form, DTOを使うような場合、 https://terasolunaorg.github.io/guideline/public_review/Overview/ApplicationLayering.html Controller, Helper, Serviceはフィールドを持たないがコンテナ管理。 Form, DTOはnewで取得 という風に切り分けますね。
7tsuno

2017/02/17 08:57

追加で、1セッションで共通で扱いたいオブジェクトや1アプリケーションで共通で扱いたいオブジェクトがあればコンテナ管理させます。 件のようなオブジェクトはすぐに生存期間を終わらせていいものなのでコンテナ管理はさせません。
msss

2017/02/20 09:02

とても分かりやすい回答ですっきりしました。 ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問