私はそうと@Autowired注釈付きフィールド(FriendList)が春APPUSERクラスがあります。
@Getter
@Setter
@Builder
@Document(collection = "app_users")
@Component
public class AppUser {
@Id
@NotBlank(message = ErrorConstants.ANDROID_USER_ACCOUNT_MANAGER_ID_IS_NULL)
private String androidUserAccountManagerId;
@NotBlank(message = ErrorConstants.NULL_NAME)
private String name;
private Friend bestFriend;
@Autowired
@Setter(AccessLevel.NONE)
private FriendList friendList;
private boolean manualBestFriendOverride;
public Optional<Friend> getFriend(String friendName) {
return friendList.getFriend(friendName);
}
public void calculateBestFriend() {
if (!manualBestFriendOverride) {
bestFriend = friendList.calculateAndReturnBestFriend();
}
}
}
アイデアは、新しいAPPUSERが作成されたすべての時間は、それはゼロからスタートして同じデフォルトfriendListを@Autowireというものでした。
APPUSERはWebController方法で作成されています。
@PostMapping("/{androidUserAccountManagerId}/setNewAppUser/{appUserName}")
public void setNewAppUser(
@NotNull @PathVariable String androidUserAccountManagerId,
@NotNull @PathVariable @Pattern(regexp = "^[A-z]{2,20}$", message = "Incorrect name format!")
String appUserName) {
databaseQueryClass.save(
AppUser.builder()
.androidUserAccountManagerId(androidUserAccountManagerId)
.name(appUserName)
.build());
}
しかし、私はfriendListフィールドは、他の方法で呼び出されているときからスローヌルポインタ例外を取得しています。基本的にオートワイヤリングはAPPUSERビルダーと連携して動作していないようです。
いくつかの読みになった後、春の順にソートされているのIoCと依存性注入のためにインスタンス化されるクラス、中に新規またはビルドを呼び出し、autowire分野に悪い習慣であるようです。
私の質問は、どのように私は賢明なこのデザインをラウンドを取得するんですか?これは行うことは可能ですか?それとも私が作成する必要が新しいインスタンスのフィールドをautowireしようとして停止する必要がありますか?また、このエンドポイントがヒットしたとき、私は、新しいユーザーをautowireできる方法はありますか?
事前にご協力いただきありがとうございます。
コンテキストのFriendListクラス:
@ToString
@EqualsAndHashCode
@Builder
public class FriendList {
@NotNull private List<Friend> listOfFriends;
public Optional<Friend> getFriend(String friendName) {
return listOfFriends.stream().filter(o -> o.getName().equals(friendName)).findAny();
}
public Friend calculateAndReturnBestFriend() {
if(listOfFriends.isEmpty()){
return null;
}
java.util.Collections.sort(listOfFriends);
return listOfFriends.get(0);
}
public boolean addToFriendList(String friendName) {
if (getFriend(friendName).isPresent()) {
return false;
}
return listOfFriends.add(
Friend.builder().name(friendName).meetingDates(new TreeSet<>()).meetUpNumber(0).build());
}
}
EDIT(申し訳ありませんが、私はこのコンテキストを逃しました...)
私はのAppConfigクラスで定義されたBeanを持っています:
@Configuration
public class AppConfig {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public FriendList getFriendList() {
return FriendList.builder().listOfFriends(new ArrayList<>()).build();
}
}
あなたについて@Autowired問題、限り、あなたは春のコンテナがあなたのために、新しいBeanを管理させるように、new演算子やビルダーを使用するための罰金です。
たとえば、次のような何かができます:
@Configuration
public class AppConfig {
@Bean
public FriendList firendList() {
return FriendList.builder()
//...
.build());
}
}
そしてその後そのようにそれを使用します。 @Import(AppConfig.class)
してくださいノート、場合上記のみ動作することをFriendListがその時点で入手可能な情報すべてとデフォルト値のように最初に作成されます。そしてまた、それだけで動作しますAPPUSERのスプリングによって管理されているコンポーネント。あなたは、コントローラでビルダーを使用してAPPUSERを作成する場合は、コントローラに@AutowiredにFriendListを必要とビルダーの上に置きます。
別のノートで友達が動的に作成され、時あなたは10人の友人を持っているし、1時間後にあなたが、あなたは別の10人の友人を持つことになりますし、あなたがそれらのすべての20を参照してくださいする必要が始まった場合、その例のために言ってみましょうされている場合別のアプローチが必要になります。最も簡単な方法は、友人のデータベースに格納することとちょうどそれらを毎回それぞれをフェッチしAPPUSERにそれらを設定します。またはキャッシュ地図からそれらを取得します。
また、使用することができます@Autowiredをそのシナリオでは、しかし、より複雑であり、あなたは直接、友人のリストをautowireする必要があります。
@Autowired
private List<Friend> friends;
そして、それぞれの友達を動的に作成する必要があります。このようなもの
Friend friend = new Friend();
context.registerBean(Friend.class, () -> friend); //context here is an ApplicationContext type aka Spring Container.
またしてこの例をチェックObjectProviderからここに。