[英]Create an Object in Spring with annotations (Inject, Autowired) or with getBean
[英]Spring Autowired and Builder annotations
我有一個 Spring AppUser 類,它有一個 @Autowired 注釋字段(FriendList),如下所示:
@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 時,它都會@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 和依賴注入由 Spring 排序,因此在正在實例化的類中調用 new 或 build 並自動裝配一個字段似乎是不好的做法。
我的問題是,我如何明智地繞過這個設計? 這是可能的嗎? 或者我應該停止嘗試在我必須創建的新實例中自動裝配一個字段? 或者,有沒有一種方法可以在遇到此端點時自動連接新用戶?
提前感謝您的幫助。
用於上下文的 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());
}
}
編輯(對不起,我錯過了這個上下文......)
我在 AppConfig 類中定義了一個 bean:
@Configuration
public class AppConfig {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public FriendList getFriendList() {
return FriendList.builder().listOfFriends(new ArrayList<>()).build();
}
}
關於您的@Autowired問題,只要您讓 spring 容器為您管理該新 bean,就可以使用新的運算符或構建器。
例如,您可以執行以下操作:
@Configuration
public class AppConfig {
@Bean
public FriendList firendList() {
return FriendList.builder()
//...
.build());
}
}
然后像這樣使用它: @Import(AppConfig.class)
請注意,只有當FriendList像默認值一樣在開始時創建時,上面的內容才有效,此時所有可用信息。 而且它只適用於由 spring 管理的AppUser組件。 如果您在控制器中使用 builder 創建 AppUser,則需要在控制器中 @Autowired FriendList 並將其設置在 builder 上。
另外,如果好友是動態創建的,假設一開始你有 10 個好友,1 小時后你將有另外 10 個好友,你需要查看所有 20 個好友,那么你需要另一種方法。 最簡單的方法是將朋友存儲在數據庫中,每次只獲取每個朋友並將它們設置在 AppUser 上。 或者從緩存映射中檢索它們。
您也可以在這種情況下使用@Autowired ,但更復雜,您需要直接自動裝配好友列表:
@Autowired
private List<Friend> friends;
每個Friend都應該動態創建。 像這樣的東西
Friend friend = new Friend();
context.registerBean(Friend.class, () -> friend); //context here is an ApplicationContext type aka Spring Container.
還可以從此處使用ObjectProvider檢查此示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.