これは私の最初のSpring
アプリケーションですので、私の無知を許してください。`@ Autowired`依存の` NullPoinerException`
が@Autowired
に依存しています。
14:08:48,415 SEVERE [com.vaadin.server.DefaultErrorHandler] (default task-4) : java.lang.NullPointerException
at com.letifer.ui.factory.BudgetTabbedPaneFactory$BudgetTabbedPane.init(BudgetTabbedPaneFactory.java:26)
at com.letifer.ui.factory.BudgetTabbedPaneFactory.createComponent(BudgetTabbedPaneFactory.java:44)
at com.letifer.ui.commons.BudgetMainUI.init(BudgetMainUI.java:44)
BudgetTabbedPaneFactory.java:
package com.letifer.ui.factory;
import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
@SpringComponent
public class BudgetAccountsFactory implements BudgetComponent {
@Autowired
private BudgetAccountMenuFactory accountMenuFactory;
@Autowired
private BudgetInfoPaneFactory infoPaneFactory;
private class BudgetAccountsLayout extends HorizontalLayout {
Component menu;
Component infoPane;
public BudgetAccountsLayout init() {
menu = accountMenuFactory.createComponent();
infoPane = infoPaneFactory.createComponent();
return this;
}
public BudgetAccountsLayout layout() {
setMargin(true);
setSizeFull();
addComponent(menu);
setComponentAlignment(menu, Alignment.TOP_LEFT);
setExpandRatio(menu, 1);
addComponent(infoPane);
setComponentAlignment(infoPane, Alignment.TOP_LEFT);
setExpandRatio(infoPane, 2);
return this;
}
}
public Component createComponent() {
return new BudgetAccountsLayout().init().layout();
}
}
このCLAS:
package com.letifer.ui.factory;
import org.springframework.beans.factory.annotation.Autowired;
import com.letifer.utils.constants.BudgetStringConstants;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.VerticalLayout;
@SpringComponent
public class BudgetTabbedPaneFactory implements BudgetComponent {
private class BudgetTabbedPane extends VerticalLayout {
private TabSheet tabSheet;
@Autowired
BudgetAccountsFactory accountsFactory;
Component accounts;
public BudgetTabbedPane init() {
tabSheet = new TabSheet();
accounts = accountsFactory.createComponent(); // <-- NullPoinerException
return this;
}
public BudgetTabbedPane layout() {
setSizeFull();
tabSheet.addTab(accounts, BudgetStringConstants.ACCOUNTS_TAB_NAME.getName());
tabSheet.addTab(new Label(BudgetStringConstants.BALANCE_TAB_NAME.getName()), BudgetStringConstants.BALANCE_TAB_NAME.getName());
tabSheet.addTab(new Label(BudgetStringConstants.STATISTICS_TAB_NAME.getName()), BudgetStringConstants.STATISTICS_TAB_NAME.getName());
addComponent(tabSheet);
return this;
}
}
public Component createComponent() {
return new BudgetTabbedPane().init().layout();
}
}
このクラスはBudgetAccountsFactory
依存
BudgetAccountsFactory.javaを持っていますsが別の2つの依存性を持ち、BudgetAccountMenuFactory
とBudgetInfoPaneFactory
BudgetAccountMenuFactory.java:
package com.letifer.ui.factory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.letifer.utils.constants.BudgetStringConstants;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.ListSelect;
import com.vaadin.ui.VerticalLayout;
@SpringComponent
public class BudgetAccountMenuFactory implements BudgetComponent {
private class BudgetAccountMenuLayout extends VerticalLayout {
private ListSelect<String> options;
public BudgetAccountMenuLayout init() {
options = new ListSelect<String>(BudgetStringConstants.ACCOUNTS_MENU_OPTION_TITLE.getName());
List<String> optionsList = new ArrayList<String>(Arrays.asList(BudgetStringConstants.ACCOUNTS_MENU_OPTION_SHOW_ACCOUNTS.getName(),
BudgetStringConstants.ACCOUNTS_MENU_OPTION_ADD.getName(), BudgetStringConstants.ACCOUNTS_MENU_OPTION_REMOVE.getName()));
Set<String> optionsSet = new HashSet<String>(optionsList);
options.setValue(optionsSet);
return this;
}
public BudgetAccountMenuLayout layout() {
setMargin(true);
setSizeFull();
addComponent(options);
return this;
}
}
public Component createComponent() {
return new BudgetAccountMenuLayout().init().layout();
}
}
BudgetInfoPaneFactory.java:
package com.letifer.ui.factory;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;
@SpringComponent
public class BudgetInfoPaneFactory implements BudgetComponent {
private class BudgetInfoPaneLayout extends VerticalLayout {
public static final String VIEW_NAME = "info";
private Label label;
public BudgetInfoPaneLayout init() {
label = new Label("INFO HERE");
return this;
}
public BudgetInfoPaneLayout layout() {
setMargin(true);
setSizeFull();
addComponent(label);
return this;
}
}
public Component createComponent() {
return new BudgetInfoPaneLayout().init().layout();
}
}
私の無知は、 "ネストされた" という依存関係を信じるように私を導きました(@Autowired
コンポーネント内の@Autowired
コンポーネント内のコンポーネント)はju大丈夫です。
しかし、明らかに私はNullPoinerException
をトップコンポーネントに取得します。
私はここで何が欠けていますか?
「依存関係内に依存関係を挿入する」インテリジェントな方法は何ですか?
ここで 'new BudgetInfoPaneLayout()'のように 'new'を使ってオブジェクトを作成すると、そのオブジェクトには注入されたオブジェクトやプロパティのようなSpringの管理コンテンツがなくなり、nullになります。新しいオブジェクトを作成するのではなく、それらをクラスに注入するだけです。 – csmckelvey
@csm_devこれは質問に対する答えです。 – solomkinmv
@csm_dev私の前提は、内部クラスと他の依存関係が同じ 'builder-pattern'を使って' Spring'によって管理される必要はないということでした。しかし、 "ネストされた依存関係"は何も問題なく注入されません。 –