私はこの問題の解決策として、stackoverflowとネット全体を調べました。ファイル内のリストとオブジェクト構造を含む投稿が私のユースケースに完全に一致しないため、私が見た解決策はありません。
これはyamlとしてのサンプルです
teddy.list:
-
name: Red
price: Five
-
name: Blue
price: One
-
name: Yellow
price: Two
-
name: Green
price: Three
これは、プロパティファイルと同じサンプルです。
teddy.list[0].name=Red
teddy.list[0].price=Five
teddy.list[1].name=Blue
teddy.list[1].price=One
teddy.list[2].name=Yellow
teddy.list[2].price=Two
teddy.list[3].name=Green
teddy.list[3].price=Three
設定のためにアプリケーションにteddy.ymlまたはteddy.propertiesファイルを提供できるようにしたいのですが。
これが私のクラスです:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
@Configuration
@PropertySource(name = "props", value = "classpath:teddy.yml", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {
@Autowired
Environment env;
@Value("${teddy.list}")
private TeddyBear[] teddyBears;
public TeddyBear[] getTeddyBears() {
return teddyBears;
}
public void setTeddyBears(TeddyBear[] teddyBears) {
this.teddyBears = teddyBears;
}
public static class TeddyBear {
private String name;
private String price;
public TeddyBear() {
}
public TeddyBear(String name, String price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
}
私はこの設定を試し、環境を使用してプロパティにアクセスし、接頭辞を削除して、「PropertySourcesPlaceholderConfigurer」のBeanを宣言しました。
現在のコードでは、Java.lang.stringをTeddyBearクラスに変換できないため、SpringはIllegalStateExceptionをスローします。
これはうまくいくはずです。
@Configuration
@PropertySource(name = "props", value = "classpath:teddy.properties", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {
private List<TeddyBear> list;
public List<TeddyBear> getList() {
return list;
}
public void setList(List<TeddyBear> list) {
this.list = list;
}
public static class TeddyBear {
private String name;
private String price;
public TeddyBear() {
}
public TeddyBear(String name, String price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
}
更新:
上記のコードは、上記で指定したプロパティファイルに対して機能します。
ymlファイルを使用する場合は、使用できます。しかし、いくつかの点があります。
1。あなたのyml構造は正しくありません、それはこのようになるはずです
teddy:
list:
-
name: Red
price: Five
-
name: Blue
price: One
-
name: Yellow
price: Two
-
name: Green
price: Three
2. yml構造(およびTeddyBearConfigのファイル名も)を修正した後、起動時にspringbootが問題を起こさないことがわかりますが、TeddBearConfigのリスト変数はnullになります。これは、springbootが@PropertySource
を通じてymlファイルを処理する方法のバグです。
3.このymlコンテンツをapplication.yml
に移動し、構成ファイルの@PropertySource
行を削除すると、すべてが完全に正常に動作することがわかります。
気を付けて。上記のSpringバージョンによっては、コードが機能しない場合があります。
これかもしれない!
private List<TeddyBear> list = new ArrayList<>;
public List<TeddyBear> getList() {
return list;
}
トリックは、SpringファクタリングがgetList()を呼び出し、TeddyBearsを新しいArrayListに追加することです。 nullポインターでは、追加するものはありません。ゲッターを捨てる。使用されていない。
あなたはさらに必要です:
@Autowired
TeddyBearConfig teddyBearConfig;
最後の発言:SpringBootTestでテストする場合は、さらにいくつかのヒントが必要になる場合があります。
コンテキストとしてテストアプリを提供します。よりエレガントな方法があるはずですが、私はこのようにしました:
@SpringBootTest(classes = {TestApplication.class,..
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) throws Throwable {
SpringApplication.run(TestApplication.class, args);
}
}
app.propertiesがTestSourcesパスの下にある場合は、TestPropertySourceを使用します。
@TestPropertySource(locations="classpath:application.properties")
ConfigurationProperties
アノテーションを使用しているので、代わりに
@Value("${teddy.list}")
private TeddyBear[] teddyBears;
あなたは直接行うことができます
private List<TeddyBear> list;
@Value
アノテーションは不要です。
また、変数名はlist
にする必要があります。これは、ymlに指定したものだからです。