我有以下问题:我有一个扩展了UI的Mainview类。在这个类中依赖注入的作品。但是这个班有一个有意见的导航员。该视图保存也包含视图的Tabsheet。现在我需要在视图中注入一个Spring @Service类。但是DI链已经坏掉了。我已经知道依赖注入链不应该被打断(我在这里通过另一个问题发现了这一点)。但我找不到保持这条链条活着的方法。有人有一个很好的tipp如何实现意见beeing也注入,尽管这样我可以在任何地方使用导航?我认为我做得太复杂甚至错了。这是我的MAINVIEW(扩展UI)类:用Vaadin和Spring Boot实现依赖注入的好实践
@Theme("valo")
@SpringUI
public class MainView extends UI {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = LoggerFactory.getLogger(MainView.class);
public static Navigator navigator;
private List<String> availableRealms = new ArrayList<>();
private ComboBox<String> select =new ComboBox<>();
@Autowired
private SpringViewProvider viewProvider;
@Override
protected void init(VaadinRequest request) {
LOGGER.info("Initializing MainView container...");
createMainView();
}
public void createMainView(){
HorizontalLayout comboBoxLayout = new HorizontalLayout();
comboBoxLayout.addComponent(select);
availableRealms.add("Master-Realm");
select.setTextInputAllowed(false);
select.setItems(availableRealms);
select.setSelectedItem(availableRealms.get(0));
LOGGER.info("Building mainView area...");
final VerticalLayout root = new VerticalLayout();
root.setSizeFull();
root.setMargin(true);
root.setSpacing(true);
setContent(root);
final CssLayout navigationBar = new CssLayout();
// navigationBar.addComponent(comboBoxLayout);
navigationBar.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
navigationBar.addComponent(createNavigationButton("Dashboard",DashBoardView.VIEW_NAME));
navigationBar.addComponent(createNavigationButton("Realm Settings",RealmSettingsView.VIEW_NAME));
navigationBar.addComponent(createNavigationButton("Client Management",ClientManagementView.VIEW_NAME));
navigationBar.addComponent(createNavigationButton("User Management",UserManagementView.VIEW_NAME));
navigationBar.addComponent(createNavigationButton("Group Management",GroupManagementView.VIEW_NAME));
comboBoxLayout.addComponent(navigationBar);
root.addComponent(comboBoxLayout);
// root.addComponent(navigationBar);
final Panel viewContainer = new Panel();
viewContainer.setSizeFull();
root.addComponent(viewContainer);
root.setExpandRatio(viewContainer, 1.0f);
LOGGER.info("Initializing navigator...");
navigator = new Navigator(this, viewContainer);
navigator.addProvider(viewProvider);
navigator.addView("", DashBoardView.class);
}
/**
* Creates a new button with listener that uses the navigator.
* @param caption
* @param viewName
* @return <b>Button</b>
*/
private Button createNavigationButton(String caption, final String viewName) {
Button button = new Button(caption);
button.addStyleName(ValoTheme.BUTTON_SMALL);
// If you didn't choose Java 8 when creating the project, convert this to an anonymous listener class
button.addClickListener(event -> getUI().getNavigator().navigateTo(viewName));
return button;
}
}
这是持有一个标签页的ClientManagementView:
@SpringView(name = ClientManagementView.VIEW_NAME)
@ViewScope
public class ClientManagementView extends VerticalLayout implements View {
private final Logger LOGGER = LoggerFactory.getLogger(ClientManagementView.class);
private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "clientmanagementview";
@Autowired
ClientOverview clientOverview;
@Autowired
ClientCreationView clientCreationView;
@Autowired
private TabSheet tabsheet;
@PostConstruct
void init() {
LOGGER.info("Initializing ClientView...");
setSizeFull();
setSpacing(true);
setMargin(true);
// TabSheet tabsheet = new TabSheet();
tabsheet.addStyleName(ValoTheme.TABSHEET_FRAMED);
this.addComponent(tabsheet);
tabsheet.addTab(clientOverview);
tabsheet.addTab(clientCreationView);
}
@Override
public void enter(ViewChangeEvent event) {
// do nothing.
}
}
而现在的客户端创建视图:
@SpringView(name = ClientCreationView.VIEW_NAME)
@ViewScope
public class ClientCreationView extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "client_creationview";
private final Logger LOGGER = LoggerFactory.getLogger(ClientCreationView .class);
@Autowired
private TabSheet tabsheet;
@Autowired
private ClientCredentialFormular clientCredentialFormular;
@Autowired
private ClientRegisterFormular clientRegisterFormular;
public ClientCreationView(){
LOGGER.info("Initializing ClientCreationView...");
this.setCaption("Register New Client");
LOGGER.info("Initializing ClientView...");
setSizeFull();
setSpacing(true);
setMargin(true);
// TabSheet tabsheet = new TabSheet();
this.addComponent(tabsheet);
tabsheet.addTab(clientRegisterFormular);
tabsheet.addTab(clientCredentialFormular);
}
@Override
public void enter(ViewChangeEvent event) {
// Do nothing...
}
}
此视图的选项卡需要注入服务类:
@SpringView(name = ClientRegisterFormular.VIEW_NAME)
@ViewScope
public class ClientRegisterFormular extends VerticalLayout implements View {
private static final long serialVersionUID = 1L;
public static final String VIEW_NAME = "client_data_formular";
private static final Logger LOGGER = LoggerFactory.getLogger(ClientRegisterFormular.class);
@Autowired
IClientService clientService;
private TextField clientIdField = new TextField("Client-Id");
private TextField rootUriField = new TextField("Root-URI");
private TextField redirectUriField = new TextField("Redirect-URI");
private Button saveButton = new Button("Save");
private Button cancelButton = new Button("Cancel");
private FormLayout form = new FormLayout();
private SaveButtonListener saveButtonListener = new SaveButtonListener(this);
private CancelButtonListener cancelButtonListener = new CancelButtonListener(this);
public ClientRegisterFormular(){
LOGGER.info("Initializing Client Data Formular...");
this.setCaption("Client Data");
this.setSizeFull();
this.setSpacing(true);
this.setMargin(true);
/*
* Panel for Formular:
*/
Panel panel = new Panel("Register Client");
panel.addStyleName("regFormPanel");
panel.setSizeUndefined(); // Shrink to fit content
//Formular:
this.form.setMargin(true);
this.form.setSizeFull();
this.clientIdField.setWidth("900px");
this.clientIdField.setRequiredIndicatorVisible(true);
form.addComponent(clientIdField);
this.rootUriField.setRequiredIndicatorVisible(true);
this.rootUriField.setWidth("900px");
form.addComponent(rootUriField);
this.redirectUriField.setRequiredIndicatorVisible(true);
this.redirectUriField.setWidth("900px");
form.addComponent(redirectUriField);
//TODO Checkboxes for
//Button-Layout:
HorizontalLayout buttonLayout = new HorizontalLayout();
this.saveButton.addClickListener(saveButtonListener);
buttonLayout.addComponent(this.saveButton);
this.cancelButton.addClickListener(this.cancelButtonListener);
buttonLayout.addComponent(this.cancelButton);
buttonLayout.setComponentAlignment(this.saveButton, Alignment.TOP_LEFT);
form.addComponent(buttonLayout);
panel.setContent(form);
this.addComponent(panel);
// this.addComponent(buttonPanel);
this.setComponentAlignment(panel, Alignment.TOP_LEFT);
}
@Override
public void enter(ViewChangeEvent event) {
// Do nothing..
}
private static class SaveButtonListener implements Button.ClickListener{
private static final long serialVersionUID = 1L;
private ClientRegisterFormular clientRegisterFormular;
public SaveButtonListener(ClientRegisterFormular clientRegisterFormular){
this.clientRegisterFormular = clientRegisterFormular;
}
@Override
public void buttonClick(ClickEvent event) {
LOGGER.info("Saving client...");
Client newClient = new Client();
newClient.setClientId(clientRegisterFormular.clientIdField.getValue());
newClient.setRootUri(this.clientRegisterFormular.rootUriField.getValue());
newClient.setRedirectUri(this.clientRegisterFormular.redirectUriField.getValue());
newClient.setClientId(UUID.randomUUID().toString());
this.clientRegisterFormular.clientService.createClient(newClient);
refreshView();
}
public void refreshView() {
MainView.navigator.navigateTo(ClientManagementView.VIEW_NAME);
}
}
private static class CancelButtonListener implements Button.ClickListener{
private static final long serialVersionUID = 1L;
private ClientRegisterFormular clientRegisterFormular;
public CancelButtonListener(ClientRegisterFormular clientRegisterFormular){
this.clientRegisterFormular = clientRegisterFormular;
}
@Override
public void buttonClick(ClickEvent event) {
LOGGER.info("Canceling Client Creation...");
refreshView();
}
public void refreshView() {
MainView.navigator.navigateTo(ClientManagementView.VIEW_NAME);
}
}
}
好的,这是一个观点。我也已经尝试过,但是我得到了一个像这样的异常:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'clientManagementView'的bean时出错:通过字段'clientCreationView'表示的不满意的依赖关系;嵌套的异常是org.springframework.beans.factory.BeanCreationException:在文件[C:\ mypath ...]中定义的名称为'clientCreationView'的bean创建时出错:所以看起来这个链已经断了。但反正好点.P.S:我更新了我的代码 – n00bst3r
以上我认为这个@Autowired 私人TabSheet标签页;可能是ClientCreationView中的一个问题。标签页是一个vaadin组件,而不是您可以自动装配的Spring组件。 –